⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nandlump.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************
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 + -