📄 nandlump.c
字号:
/*************************************************************
File Name: NANDlump.C
Last Modified Date: 2001/03/20
Programmer: MSC
Compiler:
Platform:
Usage:
Lump functions.
The lump is built on flash block. A flash block
is partitioned into N lumps.
Other Information:
**************************************************************/
#include <sys/syscall.h>
//#include "nflash/include/nflash.h"
#ifdef __WIN32__
#include "../../diskEmu/include/nfshEmu.h"
#else
#include "nflash/include/nflash.h"
#endif
//#include "../../rDebug/rdebug.h"
//#include "../../rDebug/include/rdebug.h"
#include "ffs_nand/include/FFS_NAND.h"
#include "ffs_nand/include/NANDfblk.h"
#include "ffs_nand/include/NANDfdrv.h"
#include "ffs_nand/include/NANDlump.h"
#ifdef NAND_FLASH_DISK_ID
#ifdef NAND_FFS_DEBUG
#include <ansi_c/stdio.h>
#endif
unsigned long NAND_LumpNum = 0; // the number of lumps per flash block
unsigned long NAND_TotalLumpNum = 0; // total number of lumps
// FFS_NAND.c
extern char NAND_FFS_Block[NAND_FFS_BLOCK_NUM];
//extern unsigned long *NAND_FFS_EraseCount;
extern char NAND_FFS_lumpMapTable[NAND_FFS_BLOCK_NUM * NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE / 8];
extern int NAND_FFS_curFreeLumpNo;
// marked by chilong 01/14/2002
//extern unsigned char *NAND_FlashAccessBuffer;
extern unsigned char *NAND_FlashAccessBuffer1;
extern unsigned char *NAND_FlashAccessBuffer2;
#ifdef NAND_FFS_USE_CACHE
// extern struct NAND_FFS_cacheInfo **NAND_FFS_CacheStatus;
extern unsigned char **NAND_FFS_BlockCache;
#endif
// Debug info
extern char NAND_FFS_DebugString[80];
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_CACHE_DEBUG
extern unsigned long numReadHit; /* ATA read hit count */
extern unsigned long numReadMiss; /* ATA read miss count */
extern unsigned long numWriteHit; /* ATA write hit count */
extern unsigned long numWriteMiss; /* ATA write miss count */
extern unsigned long numSwap; /* ATA cache swap count */
extern unsigned long numFlush; /* ATA cache flush count */
#endif
/**** added by chilong 01/24/2002 ****/
/*************************************************************
Function: NAND_initLump
Description:
initialize the disk lump parameters
Input:
NONE
Output:
NONE
**************************************************************/
void NAND_initLump(void)
{
NAND_LumpNum = NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE;
NAND_TotalLumpNum = NAND_FFS_BLOCK_NUM * NAND_LumpNum;
return;
}
/*************************************************************
Function: NAND_FFS_readLump
Description:
read a flash lump to buffer
Input:
lump - the flash lump number
pData - the buffer
Output:
0 succeeded
-1 lump address out of bound
Note:
The size of a lump must be a multiple of integer.
Also note that NAND_FFS_readBlock() actually read data
to its internal buffer.
*** IMPORTANT ***
This function only return the pointer to the lump within
the block which is located in an internal buffer (no
cache) or the cache (if cache is present). This is so
implemented to avoid buffer copying. Be careful don't
write directly to the memory pointed by the returned
pointer.
**************************************************************/
int NAND_FFS_readLump(int lump, unsigned char **pData)
{
int block;
int nthEntry;
unsigned char *src;
/**** added by chilong 01/17/2002 ****/
int offset;
int frameNO;
int i;
#ifdef NAND_FFS_USE_CACHE
int cacheNum;
#endif
/**** added by chilong 01/17/2002 ****/
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_readLump] lump = %d", lump);
SprintStringLn(NAND_FFS_DebugString);
#endif
if (lump == NAND_END_LUMP)
{
#ifdef NAND_FFS_DEBUG
SprintStringLn("[NAND_FFS_readLump] lump is NAND_END_LUMP");
#endif
*pData = NULL;
return -1;
}
// get the location of the lump
NAND_lump2Block(lump, &block, &nthEntry);
if (block == -1 || nthEntry == -1)
{
// errno set by NAND_lump2Block()
*pData = NULL;
return -1; // invalid block
}
#ifdef NAND_FFS_USE_CACHE
///* 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)
{
*pData = NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE;
return 0;
}
else
{
// errno set by NAND_FFS_putBlockInCache()
return -1;
}
// marked by chilong 01/25/2002 */
/**** modified by chilong 01/24/2002 ****/
/*
cacheNum = NAND_FFS_searchBlockInCache(block);
if (cacheNum > -1)
{
#ifdef NAND_FFS_CACHE_DEBUG
numReadHit++;
#endif
*pData = NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE;
return 0;
}
else
{
#ifdef NAND_FFS_CACHE_DEBUG
numReadMiss++;
#endif
offset = (block + NAND_FFS_START_BLOCK)* NAND_FLASH_BLOCK_SIZE + nthEntry * NAND_LUMP_SIZE;
frameNO = NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
*pData = NAND_FlashAccessBuffer1;
for (i = 0; i < frameNO; i++)
{
sc_disableInt();
nfshReadFrame(offset, *pData);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
*pData += NFLASH_FRAME_SIZE;
}
*pData = NAND_FlashAccessBuffer1;
return 0;
}
*/
/**** modified by chilong 01/24/2002 ****/
#else
offset = (block + NAND_FFS_START_BLOCK)* NAND_FLASH_BLOCK_SIZE + nthEntry * NAND_LUMP_SIZE;
frameNO = NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
*pData = NAND_FlashAccessBuffer1;
for (i = 0; i < frameNO; i++)
{
sc_disableInt();
nfshReadFrame(offset, *pData);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
*pData += NFLASH_FRAME_SIZE;
}
*pData = NAND_FlashAccessBuffer1;
return 0;
#endif
/* marked by chilong 01/24/2002
// read the flash block in buffer
if (NAND_FFS_readBlock(block, &src, 0) == -1)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " block invalid");
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_readBlock()
*pData = NULL;
return -1;
}
if (src == NULL)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " read block failed!");
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_Errno = ERROR_FLASH_BLOCK_READ;
*pData = NULL;
return -1;
}
// go to the target lump in the block
*pData = (unsigned char *)((unsigned long)src + nthEntry * NAND_LUMP_SIZE);
return 0;
marked by chilong 01/24/2002 */
}
/*************************************************************
Function: NAND_FFS_writeLump
Description:
write a lump from buffer to flash
Input:
lump - the flash lump number
pData - the buffer
Output:
0 succeeded
-1 lump address out of bound
Note:
The size of a lump must be a multiple of integer
Also note that NAND_FFS_readBlock() actually read data
to its internal buffer.
**************************************************************/
int NAND_FFS_writeLump(int lump, unsigned char *pData)
{
int block;
int nthEntry;
unsigned char *base;
int *src;
int *des;
int i;
int offset;
int frameNO;
#ifdef NAND_FFS_USE_CACHE
int cacheNum;
#endif
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_writeLump] lump = %d", lump);
SprintStringLn(NAND_FFS_DebugString);
#endif
// printf("{W_Lump=%d}", lump);//jason
if (lump == NAND_END_LUMP)
{
#ifdef NAND_FFS_DEBUG
SprintStringLn("[NAND_FFS_writeLump] lump is NAND_END_LUMP");
#endif
// marked by chilong 01/10/2002
// *pData = NULL;
return -1;
}
// get the location of the lump
NAND_lump2Block(lump, &block, &nthEntry);
if (block == -1 || nthEntry == -1)
{
// errno set by NAND_lump2Block()
return -1; // invalid block
}
#ifdef NAND_FFS_USE_CACHE
#ifdef NAND_FFS_CACHE_DEBUG
cacheNum = NAND_FFS_putBlockInCache(block, 1, 0);
#else
cacheNum = NAND_FFS_putBlockInCache(block, 1);
#endif
if (cacheNum > -1)
{
#ifdef NAND_FFS_CACHE_DEBUG
numWriteHit++;
#endif
// block in cache, write to cache
src = (int *)pData;
des = (int *)((unsigned long)NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE);
if (src != des)
{
for (i = 0; i < NAND_LUMP_SIZE; i += sizeof(int))
*des++ = *src++;
}
NAND_FFS_modifyCache(cacheNum);
return 0;
}
else
{
// errno set by NAND_FFS_putBlockInCache()
return -1;
}
#else
// read the respective lump structure and check
// if it's been erased (2 --> TYPE_FREE in NAND_readLumpStructure() )
if (NAND_readLumpStructure(lump, 2) != NULL)
{
offset = (NAND_FFS_START_BLOCK+block) * NAND_FLASH_BLOCK_SIZE + nthEntry * NAND_LUMP_SIZE;
frameNO = NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
for (i = 0; i < frameNO; i++)
{
sc_disableInt();
nfshProgramFrame(offset, pData);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
pData += NFLASH_FRAME_SIZE;
}
return 0;
}
// need to read the block only if there are more than one lump per block
if (NAND_LumpNum > 1)
{
if (NAND_FFS_readBlock(block, &base, 1) == -1)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " read block failed!");
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_readBlock()
return -1;
}
if (base == NULL)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " read block failed!");
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_Errno = ERROR_FLASH_BLOCK_READ;
return -1;
}
// go to the target lump in the block
src = (int *)pData;
des = (int *)((unsigned long)base + nthEntry * NAND_LUMP_SIZE);
if (src != des)
{
for (i = 0; i < NAND_LUMP_SIZE; i += sizeof(int))
*des++ = *src++;
}
}
else
{
base = pData;
}
if (NAND_FFS_writeBlock(block, base) == -1)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " write block failed!");
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_writeBlock()
return -1;
}
return 0;
#endif
}
/*************************************************************
Function: NAND_FFS_freeLumpLink
Description:
free all blocks in a file block link
Input:
startBlock - the starting block in the link
Output:
NONE
**************************************************************/
void NAND_FFS_freeLumpLink(int startLumpNo)
{
struct NAND_diskLump *curLump;
struct NAND_diskLump *nextLump;
int curLumpNo;
int nextLumpNo;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_freeLumpLink] startLumpNo: %d", startLumpNo);
SprintStringLn(NAND_FFS_DebugString);
#endif
curLumpNo = startLumpNo;
while (curLumpNo != NAND_END_LUMP)
{
if (NAND_checkLump(curLumpNo) == -1)
return; // block address out of bound
if (NAND_FFS_readLump(curLumpNo, (unsigned char**)&curLump) == -1)
return;
if (curLump == NULL)
return;
nextLumpNo = curLump->nextLump;
NAND_FFS_freeLump(curLumpNo);
curLumpNo = nextLumpNo;
}
return;
}
/*************************************************************
Function: NAND_FFS_freeLump
Description:
release a disk lump back to the NAND_FFS
Input:
lumpNo - the number of the lump that is going to be released
Output:
**************************************************************/
void NAND_FFS_freeLump(int lumpNo)
{
enterKernelCriticalSection();
NAND_FFS_freeLump_r(lumpNo);
exitKernelCriticalSection();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -