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

📄 fsmplr.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 5 页
字号:
  ###	If the designated sector is not found, the function returns ERR_NOTEXIST.
  ###   Otherwise, the function returns ERR_NONE.
  ###
 */

static uint32 DfsPlrEntryDeleting(
	uint32		first_lsn, 
	uint32		entry_sector_psn, 
	uint16		entry_num, 
	uint32 *	Psn2LsnP, 
	FsmDevObjHdrT * pDev, 
	uint32		block_size, 
	uint32		block_num
	)
{
	uint32		sector_size;
	uint32		max_psn;
	uint16		block_sectors;

	uint32		psn;
	uint32		lsn;	
	uint32		sector_addr;
	uint16		sector_status;
	uint16		sector_type;

	uint32		entry_addr;
	uint16		entry_status;

	uint8		end_flag;

	uint32		hw_status;

	DEV_WRITE_FUNCPTR	DevWrite = pDev->DevDrvP->FsmDevWrite;
	DEV_READ_FUNCPTR	DevRead  = pDev->DevDrvP->FsmDevRead;


	#ifdef DEBUG_FSM
	MonPrintf("Enter Interface DfsPlrEntryDeleting!\n");
	#endif

	block_sectors = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorsPerBlock;
	sector_size   = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorSize;
	max_psn       = ((FsmFlashMediaT *)(pDev->MediaObjP))->MaxPsn;

	lsn = first_lsn;

	end_flag = 0;

	while(lsn != (uint32)(-1))
	{
		end_flag = 0;

		/* search the sector linked to the entry in ENTRY_DELETING status. */
		for(psn = 0; psn < max_psn; psn++)
		{
			if(Psn2LsnP[psn] == lsn)
			{
				end_flag = 1;
				break;
			}
		}

		if(end_flag == 0)
			return ERR_NOTEXIST;

		sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);

		hw_status = DevRead(pDev, 
							(uint8 *)&sector_status, 
							sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
							FIELD_SIZE(FsmFlashSectorHdrT, Status)
							);

		if(hw_status != HW_ERR_NONE)
			return ERR_READ;

		/* set sector status to SECTOR_DELETING and read nextlsn for searching the next sector in link. */
		if(sector_status == SECTOR_VALID)
		{
			sector_status = SECTOR_DELETING;

			hw_status = DevWrite(pDev, 
								 (uint8 *)&sector_status, 
								 sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
								 FIELD_SIZE(FsmFlashSectorHdrT, Status)
								 );

			if(hw_status != HW_ERR_NONE)
				return ERR_WRITE;
		}
		else if(sector_status != SECTOR_DELETING)
			return ERR_EXIST;		

		hw_status = DevRead(pDev, 
							(uint8 *)&lsn, 
							sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn), 
							FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
							);

		if(hw_status != HW_ERR_NONE)
			return ERR_READ;	
	}

	/* read sector type to judge the entry is for file or for item. */
	sector_addr = DfsGetAddr(entry_sector_psn, block_sectors, block_size, sector_size);

	hw_status = DevRead(pDev,
					 	(uint8 *)&sector_type, 
						sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Type), 
						FIELD_SIZE(FsmFlashSectorHdrT, Type)
						);

	if(hw_status != HW_ERR_NONE)
		return ERR_READ;

	/* invalidate directory entry. */

	entry_status = ENTRY_INVALID;

	if(sector_type == SECTOR_TYPE_FDE)
	{
		entry_addr = sector_addr + sizeof(FsmFlashSectorHdrT)
					 + entry_num * sizeof(FsmFileDirEntryT);

		hw_status = DevWrite(pDev, 
							 (uint8 *)&entry_status, 
							 entry_addr + FIELD_OFFSET(FsmFileDirEntryT, Status), 
							 FIELD_SIZE(FsmFileDirEntryT, Status)
							 );

		if(hw_status != HW_ERR_NONE)
			return ERR_WRITE;
	}
	else
	{
		entry_addr = sector_addr + sizeof(FsmFlashSectorHdrT)
					 + entry_num * sizeof(FsmItemDirEntryT);

		hw_status = DevWrite(pDev, 
							 (uint8 *)&entry_status, 
							 entry_addr + FIELD_OFFSET(FsmItemDirEntryT, Status), 
							 FIELD_SIZE(FsmItemDirEntryT, Status)
							 );

		if(hw_status != HW_ERR_NONE)
			return ERR_WRITE;
	}

	/* invalidate old sectors linked to the directory entry. */

	sector_status = SECTOR_INVALID;

	lsn = first_lsn;

	while(lsn != (uint32)(-1))
	{
		end_flag = 0;

		for(psn = 0; psn < max_psn; psn++)
		{
			if(Psn2LsnP[psn] == lsn)
			{
				end_flag = 1;
				break;
			}
			
		}

		if(end_flag == 0)
			return ERR_NOTEXIST;

		sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);

		hw_status = DevWrite(pDev, 
							 (uint8 *)&sector_status, 
							 sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
							 FIELD_SIZE(FsmFlashSectorHdrT, Status)
							 );

		if(hw_status != HW_ERR_NONE)
			return ERR_WRITE;

		Psn2LsnP[psn] = DIRTYLSN;

		hw_status = DevRead(pDev, 
							(uint8 *)&lsn, 
							sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn), 
							FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
							);

		if(hw_status != HW_ERR_NONE)
			return ERR_READ;	
	}

	#ifdef DEBUG_FSM
	MonPrintf("Exit Interface DfsPlrEntryDeleting successfully!\n");
	#endif

	return ERR_NONE;
}

/*#############################################################################
  ### DfsPlrEntryUpdating
  ###
  ### DESCRIPTION:
  ###   Validate all sectors linked to the entry in ENTRY_UPDATING status.
  ###
  ### PARAMETERS:
  ###    IN:  first_lsn - first sector lsn linked to the directory entry in 
  ###			ENTRY_ALLOCATED status.
  ###	      Psn2LsnP - pointer to the Psn2Lsn map.
  ###	      pDev - poiter to designated FsmDevObjHdrT of data file system.
  ###	      block_size - flash block size.
  ###	      block_num - flash block number.
  ###    OUT: 
  ###
  ### RETURNS:
  ###   If read operation is not successful,  the function returns ERR_READ.
  ###	If write operation is not successful,  the funciton returns ERR_WRITE.
  ###	If the designated sector found is not in correct status, the function returns ERR_EXIST.
  ###	If the designated sector is not found, the function returns ERR_NOTEXIST.
  ###   Otherwise, the function returns ERR_NONE.
  ###
 */
static uint32 DfsPlrEntryUpdating(
	uint32		first_lsn, 
	uint32 *	Psn2LsnP, 
	FsmDevObjHdrT * pDev, 
	uint32		block_size, 
	uint32		block_num
	)
{
	uint32		max_psn;
	uint32		sector_size;
	uint16		block_sectors;

	uint32		psn, old_psn, new_psn;
	uint32		lsn;	
	uint16		sector_status;
	uint8		new_flag, old_flag;
	uint32		sector_addr;
	uint32		err_status;
	uint32		hw_status;

	DEV_READ_FUNCPTR	DevRead  = pDev->DevDrvP->FsmDevRead;


	#ifdef DEBUG_FSM
	MonPrintf("Enter Interface DfsPlrEntryUpdating!\n");
	#endif

	block_sectors = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorsPerBlock;
	sector_size   = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorSize;
	max_psn       = ((FsmFlashMediaT *)(pDev->MediaObjP))->MaxPsn;

	lsn = first_lsn;

	while(lsn != (uint32)(-1))
	{
		new_flag = 0;
		old_flag = 0;

		/* search the sector linked to the entry. */
		for(psn = 0; psn < max_psn; psn++)
		{
			if(Psn2LsnP[psn] == lsn)
			{
				sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);

				hw_status = DevRead(pDev, 
									(uint8 *)&sector_status, 
									sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
									FIELD_SIZE(FsmFlashSectorHdrT, Status)
									);

				if(hw_status != HW_ERR_NONE)
					return ERR_READ;

				if(sector_status == SECTOR_VALID)
				{
					old_psn = psn;
					old_flag = 1;
				}
				else if(sector_status == SECTOR_APPENDING)
				{
					new_psn = psn;
					new_flag = 1;
				}
			}
		}

		if(new_flag == 1)
		{
			/* validate all new sectors linked to the entry. */
			err_status = DfsPlrSecAppending(new_psn, Psn2LsnP, pDev, block_size, block_num);

			if(err_status != ERR_NONE)
				return err_status;

			break;
		}
		else
		{
			if(old_flag == 1)
			{
				sector_addr = DfsGetAddr(old_psn, block_sectors, block_size, sector_size);

				hw_status = DevRead(pDev, 
									(uint8 *)&lsn, 
									sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn), 
									FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
									);

				if(hw_status != HW_ERR_NONE)
					return ERR_READ;	
			}
			else
				return ERR_NOTEXIST;		
		}
	}

	#ifdef DEBUG_FSM
	MonPrintf("Exit Interface DfsPlrEntryUpdating successfully!\n");
	#endif

	return ERR_NONE;	
}

/*#############################################################################
  ### DfsPlrItemEntry
  ###
  ### DESCRIPTION:
  ###   Search old item directory entry whose firstlsn is the same with the 
  ###	firstlsn of the item directory entry in ENTRY_UPDATING status.If the 
  ###	designated entry is found,  its status will be modified to ENTRY_INVALID.
  ###
  ### PARAMETERS:
  ###    IN:  first_lsn - firstlsn information of the item directory entry in 
  ###			ENTRY_UPDATING status.
  ###	      Psn2LsnP - pointer to the Psn2Lsn map.
  ###	      pDev - poiter to designated FsmDevObjHdrT of data file system.
  ###	      block_size - flash block size.
  ###	      block_num - flash block number.
  ###    OUT: 
  ###
  ### RETURNS:
  ###   If read operation is not successful,  the function returns ERR_READ.
  ###	If write operation is not successful,  the funciton returns ERR_WRITE.
  ###	Otherwise,  the function returns ERR_NONE.
  ###
 */

static uint32 DfsPlrItemEntry(
	uint32		first_lsn, 
	uint32 *	Psn2LsnP, 
	FsmDevObjHdrT * pDev, 
	uint32		block_size, 
	uint32		block_num
	)
{
	uint32		max_psn;
	uint32		sector_size;
	uint16		block_sectors;

	uint32		max_entry;
	uint32		psn, lsn;

	uint32		sector_addr;
	uint16		sector_type;
	uint16		sector_status;

	uint32		i;
	uint32		entry_addr;
	uint16		entry_status;
	uint16		entry_status_msk;
	uint32		entry_first_lsn;

	uint32		hw_status;
	uint8		end_flag;

	DEV_WRITE_FUNCPTR	DevWrite = pDev->DevDrvP->FsmDevWrite;
	DEV_READ_FUNCPTR	DevRead  = pDev->DevDrvP->FsmDevRead;


	#ifdef DEBUG_FSM
	MonPrintf("Enter Interface DfsPlrItemEntry!\n");
	#endif

	block_sectors = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorsPerBlock;
	sector_size   = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorSize;
	max_psn       = ((FsmFlashMediaT *)(pDev->MediaObjP))->MaxPsn;

	/* maximum item entries in a sector. */
	max_entry = sector_size / sizeof(FsmItemDirEntryT);

	end_flag = 0;

	for(psn = 0; psn < max_psn; psn++)
	{
		lsn = Psn2LsnP[psn];

		if((lsn == EMPTYLSN) || (lsn == DIRTYLSN))
			continue;

		sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);

		hw_status = DevRead(pDev, 
							(uint8 *)&sector_type, 
							sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Type), 
							FIELD_SIZE(FsmFlashSectorHdrT, Type)
							);

		if(hw_status != HW_ERR_NONE)
			return ERR_READ;

		if(sector_type == SECTOR_TYPE_IDE)
		{
			hw_status = DevRead(pDev,
								(uint8 *)&sector_status, 
								sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
								FIELD_SIZE(FsmFlashSectorHdrT, Status)
								);

			if(hw_status != HW_ERR_NONE)
				return ERR_READ;

			if(sector_status != SECTOR_VALID)
				continue;

			for(i = 0; i < max_entry; i++)
			{
				entry_addr = sector_addr + sizeof(FsmFlashSectorHdrT)
							 + i * sizeof(FsmItemDirEntryT);

				hw_status = DevRead(pDev, 
									(uint8 *)&entry_status, 
									entry_addr+ FIELD_OFFSET(FsmItemDirEntryT, Status) , 
									FIELD_SIZE(FsmItemDirEntryT, Status)
									);

				if(hw_status != HW_ERR_NONE)
					return ERR_READ;

				/* fix entry status to predefined value. */
				if((entry_status_msk = VALID_ENTRY_STATE(entry_status)) != 0)
				{
					entry_status = FIX_ENTRY_STATE(entry_status_msk, entry_status);
				}

				if(entry_status == ENTRY_EMPTY)
					break;

				else if(entry_status == ENTRY_VALID)
				{
					hw_status = DevRead(pDev, 
										(uint8 *)&entry_first_lsn, 
										entry_addr + FIELD_OFFSET(FsmItemDirEntryT, FirstLsn), 
										FIELD_SIZE(FsmItemDirEntryT, FirstLsn)
										);

					if(hw_status != HW_ERR_NONE)
						return ERR_READ;

					if(entry_first_lsn == first_lsn)
					{
						entry_status = ENTRY_INVALID;

						hw_status = DevWrite(pDev, 
											 (uint8 *)&entry_status, 
											 entry_addr + FIELD_OFFSET(FsmItemDirEntryT, Status), 
									  		 FIELD_SIZE(FsmItemDirEntryT, Status)
									  		 );

						if(hw_status != HW_ERR_NONE)
							return ERR_WRITE;

						end_flag = 1;

						break;
					}
				} /* end if ENTRY_VALID. */ 
			} /* end for (i = 0; i < max_entry; i++) */
		} /* if(sector_type == SECTOR_TYPE_IDE) */

		if(end_flag == 1)
			break;		
	} /* end for(psn = 0; psn < max_psn; psn++). */

	#ifdef DEBUG_FSM
	MonPrintf("Exit Interface DfsPlrItemEntry successfully!\n");
	#endif

	return ERR_NONE;	
}


/*#############################################################################
  ### DfsPlrFileEntry
  ###
  ### DESCRIPTION:
  ###   Search old file directory entry whose firstlsn is the same with the 
  ###	firstlsn of the file directory entry in ENTRY_UPDATING status.If the 
  ###	designated entry is found,  its status will be modified to ENTRY_INVALID.
  ###
  ### PARAMETERS:
  ###    IN:  first_lsn - firstlsn information of the file directory entry in 
  ###			ENT

⌨️ 快捷键说明

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