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

📄 nandlump.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************
Function: RD_freeLump_r
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_r(int lumpNo)
{
  int i;
  int block, nthEntry;
  unsigned char *base;
  int *src;
  
#ifdef NAND_FFS_DEBUG
  sprintf(NAND_FFS_DebugString, "[NAND_FFS_freeLump] lumpNo: %d", lumpNo);
  SprintStringLn(NAND_FFS_DebugString);
#endif
  if (lumpNo == NAND_END_LUMP)
	return;

  NAND_lump2Block(lumpNo, &block, &nthEntry);
  if (block == -1 || nthEntry == -1)
  {
	// errno set by NAND_lump2Block()
	return;
  }

  // continue next block if the current one is not usable for AP storage
  if (NAND_FFS_Block[block] == NAND_FB_UNUSED)
  	return;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "[NAND_FFS_freeLump] Erasing block %d", lumpNo);
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  if (NAND_FFS_readBlock(block, &base, 0) == -1)
  	return;
  	
  if (NAND_FFS_eraseFlashBlock(block) == -1)
  {
	#ifdef NAND_FFS_DEBUG
		sprintf(NAND_FFS_DebugString, "[NAND_FFS_freeLump] Erase block %d error", lumpNo);
		SprintStringLn(NAND_FFS_DebugString);
	#endif

	// errno set by NAND_FFS_eraseFlashBlock()
	return;
  }
  
  // !!NOTE: we assume any int type contains 4 bytes
  src = (int *) ((unsigned long)base + NAND_LUMP_SIZE * nthEntry);
  for (i = 0; i < NAND_LUMP_SIZE; i+=sizeof(int))
  	*src++ = 0xFFFFFFFF;

  // set NAND_FFS_lumpMapTable
  NAND_FFS_lumpMapTable[lumpNo/8] &= ~(1 << (lumpNo%8));
  	
  // restore those used lumps
  for (i = 0; i < NAND_LumpNum; i++)
  {
  	if (i != nthEntry)
  	{
  		if (NAND_FFS_writeLump(block*NAND_LumpNum+i, base + i*NAND_LUMP_SIZE) == -1)
  			return;
  	}
  }

  NAND_FFS_Block[block] = NAND_FB_OK;
}


/*************************************************************
Function: NAND_getNextLump
Description:
	get the total data size in a link of lumps
Input:
	lump - the target lump
Output:
	the next lump
**************************************************************/
/* marked by chilong 12/20/2001 temporarily
int NAND_getNextLump(int lump)
{
//  int block;
//  int nthEntry;
  struct NAND_diskLump *lumpPtr;
  lumpPtr = NAND_readLumpStructure(lump, 0);
  if (lumpPtr == NULL)
  {
	// errno set by NAND_readLumpStructure()
	return NAND_END_LUMP;
  }

  return(lumpPtr->nextLump);
}
   marked by chilong 12/20/2001 temporarily */



/*************************************************************
Function: NAND_totalDataSizeInLumpLink
Description:
	get the total data size in a link of lumps
Input:
	lump - the beginning lump
Output:
	the total data size
**************************************************************/
/* marked by chilong 12/20/2001 temporarily
unsigned long NAND_totalDataSizeInLumpLink(int lump)
{
  unsigned long totalSize = 0;
//  int block;
//  int nthEntry;
  struct NAND_diskLump *lumpPtr;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "[NAND_totalDataSizeInLumpLink] lump=%d", lump);
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  // loop through the lump link
  while (lump != NAND_END_LUMP)
  {
	lumpPtr = NAND_readLumpStructure(lump, 0);
	if (lumpPtr == NULL)
	{
		// errno set by NAND_readLumpStructure()
		return totalSize;
	}

	totalSize += lumpPtr->dataSize;

	lump = lumpPtr->nextLump;
  }

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "    size=%d", totalSize);
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  return totalSize;
}
   marked by chilong 12/20/2001 temporarily */



/*************************************************************
Function: NAND_deleteLumpChain
Description:
	delete the lumps in the chain
Input:
	beginLump - the beginning lump
	keepFirst - keep the first lump in the link?
			0: no
			1: yes
	dataSize - the size of data to be kept if keepFirst is 1
Output:
	0	succeeded
	1	failed - memory allocation error
	2	failed - flash write error
	3	failed - flash read error
	4	failed - invalid block
**************************************************************/

/* marked by chilong 12/20/2001 temporarily

int NAND_deleteLumpChain(int beginLump, int keepFirst, unsigned long dataSize)
{
  struct dLinkList lumpList;
  struct dLinkList *currLumpNode;
  struct dLinkList *prevLumpNode;
  int currLump;
  int prevFBlock;
  int *des;
  int i;
  int block;
  int nthEntry;
  int *base;
  struct NAND_diskLump *lumpPtr;

  initDLinkList(&lumpList);

  // build the lump list sorted by lump addresses in ascending order
  // this list allows the lumps located in the same flash block to be
  //   easily located and handled as a batch
  currLump = beginLump;

  if (keepFirst == 1)
	keepFirst = beginLump;
  else
	keepFirst = NAND_END_LUMP;

  while (currLump != NAND_END_LUMP)
  {
	// insert the current lump into the lump list
	currLumpNode = lumpList.back;
	prevLumpNode = &lumpList;

	// find a appropriate position in the list for the current lump
	while (currLumpNode != NULL)
	{
		if ((unsigned long)currLump < (unsigned long)(currLumpNode->elementPointer))
		{
			// the address in the current node is larger
			// the new node should be inserted before the current node
			break;
		}

		prevLumpNode = currLumpNode;
		currLumpNode = currLumpNode->back;
	}

	// the new node is inserted behind prevLumpNode
	currLumpNode = (struct dLinkList *)sc_malloc(sizeof(struct dLinkList));
	if (currLumpNode == NULL)
	{
		// allocation failed
		freeDLinkList(&lumpList);
		NAND_FFS_Errno = ERROR_ALLOC_MEM;
		return 1;
	}

	// setup lump node information for the current lump
	currLumpNode->elementPointer = (void *)currLump;
	currLumpNode->prev = prevLumpNode;
	currLumpNode->back = prevLumpNode->back;

	// update links
	prevLumpNode->back = currLumpNode;
	if (currLumpNode->back != NULL)
		((struct dLinkList *)(currLumpNode->back))->prev = currLumpNode;

	// get next lump
	currLump = NAND_getNextLump(currLump);
  }

  // the lump list has been built, start erasing
  prevFBlock = NAND_END_LUMP;
  currLumpNode = lumpList.back;
  base = NULL;
  while (currLumpNode != NULL)
  {
	// find the flash block in which the lump is stored and its location in the block
	NAND_lump2Block((int)currLumpNode->elementPointer, &block, &nthEntry);
	if (block != -1 && nthEntry != -1)
	{
		// flash block number is valid, proceed with delete
		// To limit erase count, we collect all lumps stored in the same flash block
		//   and delete them all in one erase.
		// Note that all lumps are already sorted ascendingly according to their addresses
		//   in above.
		if (prevFBlock != block)
		{
			// a new block will be needed, write back the previous block
			if (prevFBlock != NAND_END_LUMP && base != NULL)
			{
				// the previous block has been completed
				// write the block back to flash
				if (NAND_FFS_writeBlock(prevFBlock, (unsigned char *)base) == -1)
				{
					// flash erase error
					freeDLinkList(&lumpList);
					// errno set by NAND_FFS_writeBlock()
					return 2;
				}
			}

			// read the new flash block in buffer
			prevFBlock = block;
			if (NAND_FFS_readBlock(block, (unsigned char **)&base) == -1)
			{
				freeDLinkList(&lumpList);
				// errno set by NAND_FFS_readBlock()
				return 3;
			}

			if (base == NULL)
			{
				NAND_FFS_Errno = ERROR_FLASH_BLOCK_READ;
				return -1;
			}
		}

		// the corresponding flash block is within the buffer, erase the part that
		//   belongs to the current lump if it needs not be spared
		if (keepFirst == (int)currLumpNode->elementPointer && keepFirst != NAND_END_LUMP)
		{
			sysTime now;

			// have to keep this first lump, but the lump information have to be updated
			lumpPtr = (struct NAND_diskLump *)((unsigned long)base + NAND_LUMP_SIZE * nthEntry);

			lumpPtr->dataSize = dataSize;

			sc_getTime(&now);
			lumpPtr->updateTime = (now.hour << 11) + (now.minute << 5) + (now.second >> 1);
			lumpPtr->updateDate = (now.year << 9) + (now.month << 5) + now.day;

			lumpPtr->nextLump = NAND_END_LUMP;
			keepFirst = NAND_END_LUMP;
		}
		else
		{
			// this block can be totally deleted
			des = (int *)((unsigned long)base + NAND_LUMP_SIZE * nthEntry);
			for (i = 0; i < NAND_LUMP_SIZE; i += sizeof(int))
				*des++ = 0xFFFFFFFF;

			// at least one lump in the current block is freed, the block is
			//   absolutely not full
//			NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] & (~NAND_BLOCK_FULL_BIT_MASK);
			NAND_FFS_Block[block] = NAND_FB_OK;
		}
	}

	currLumpNode = currLumpNode->back;
  }

  // the last flash block has not yet been written to flash
  if (prevFBlock != NAND_END_LUMP && base != NULL)
  {
	// the previous block has been completed
	// write the block back to flash
	if (NAND_FFS_writeBlock(prevFBlock, (unsigned char *)base) == -1)
	{
		// flash erase error
		freeDLinkList(&lumpList);
		// errno set by NAND_FFS_writeBlock()
		return 2;
	}
  }

  freeDLinkList(&lumpList);
  return 0;
}
   marked by chilong 12/20/2001 temporarily */

/*************************************************************
Function: NAND_checkBadLump
Description:
	check if the requested lump can be used
Input:
	lumpNo - the lump number
Output:
	0 - ok
	-1 - bad
Note:
**************************************************************/
int NAND_checkBadLump(int lumpNo)
{
#if 0
  int i;
  int numPagesOfLump;
  
  numPagesOfLump = NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
  for ( i=0;i< numPagesOfLump;i++ )
  {
//jason  	if (!(nfshCheckBadPage(NAND_FFS_START_BLOCK*NAND_FLASH_BLOCK_SIZE + lumpNo*NAND_LUMP_SIZE+i*NFLASH_FRAME_SIZE)) )
//		return -1;
  }
  
  return 0;
#endif
	if ( nfshCheckBadBlock( (unsigned long) NAND_FFS_START_BLOCK*NAND_FLASH_BLOCK_SIZE + lumpNo*NAND_LUMP_SIZE ) )
		return 0;
	else 
		return -1;
}


/*************************************************************
Function: NAND_countFreeLumpsInBlock
Description:
	counts the number of free lumps in a flash block
Input:
	block - the specified flash block
	pNthLumpEntry - the pointer to the lump entry which will
			be used in NAND_findFreeLump()
Output:
	number of free lumps
	-1 if the block is invalid
Note:
	Note that NAND_FFS_readBlock() read block content into
	its internal buffer.
**************************************************************/

/**** modified by chilong 01/17/2002 ****/
int NAND_countFreeLumpsInBlock(int block, int *pNthLumpEntry)
{
  int count;
  int i;
  int lump;
  
  // marked by chilong 01/25/2002
  struct NAND_diskLump *lumpPtr;

  count = 0;
  // lump now points to the head of the internal buffer of NAND_FFS_readBlock()
  // check every lump in the buffer
  lump = block * NAND_LumpNum;

  for (i = 0; i < NAND_LumpNum; i++)
  {
  	if( ((NAND_FFS_lumpMapTable[(lump+i)/8] >> ((lump+i)%8)) & 0x01) == 0x01)
  		continue;

	// added by chilong 01/25/2002
	count++;
	/* marked by chilong 01/25/2002  	
  	// chilong: NAND_readLumpStructe has invoked checkLump() to check
  	// 	if the lump is bad or out of bound
	lumpPtr = NAND_readLumpStructure(lump+i, 2);
	if (lumpPtr != NULL)
	{
		count++;
		
		if (*pNthLumpEntry == NAND_END_LUMP)
			*pNthLumpEntry = i;
	}

	lumpPtr = (struct NAND_diskLump *)((unsigned long)lumpPtr + NAND_LUMP_SIZE);
	   marked by chilong 01/25/2002 */
	
  }

  if (count == 0)
  {
	// the block is full
//	NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
	NAND_FFS_Block[block] = NAND_FB_FULL;
  }

  return count;
}

/**** modified by chilong 01/17/2002 ****/

/* marked by chilong 01/17/2002
int NAND_countFreeLumpsInBlock(int block)
{
  int count;
  int i;
  int lump;
  struct NAND_diskLump *lumpPtr;

  count = 0;
  // lump now points to the head of the internal buffer of NAND_FFS_readBlock()
  // check every lump in the buffer
  lump = block * NAND_LumpNum;

  for (i = 0; i < NAND_LumpNum; i++)
  {
	lumpPtr = NAND_readLumpStructure(lump, 2);
	if (lumpPtr != NULL)
//		if (lumpPtr->type == NAND_LUMP_TYPE_FREE)
		count++;

//	lumpPtr = (struct NAND_diskLump *)((unsigned long)lumpPtr + NAND_LUMP_SIZE);
  }

  if (count == 0)
  {
	// the block is full
//	NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
	NAND_FFS_Block[block] = NAND_FB_FULL;
  }

  return count;
}
   marked by chilong 01/17/2002 */


/*************************************************************
Function: NAND_findFreeLump
Description:
	find a free lump
Input:
	none
Output:
	the lump number
	NAND_END_LUMP if error
**************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -