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

📄 fsmplr.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 5 页
字号:

					break;

				case ENTRY_UPDATING:
					hw_status = DevRead(pDev, 
										(uint8 *)&entry_firstlsn, 
										entry_address + FIELD_OFFSET(FsmFileDirEntryT, FirstLsn), 
										FIELD_SIZE(FsmFileDirEntryT, FirstLsn)
										);

					if(hw_status != HW_ERR_NONE)
						return ERR_READ;

					#ifdef DEBUG_FSM
					MonPrintf("File entry whose first lsn is %d is "
						"in ENTRY_UPDATING status in the No.%d entry of No.%d sector!\n",
						entry_firstlsn, i, Psn);
					#endif

					/* recover sectors linked to this entry. */
					err_status = DfsPlrEntryUpdating(entry_firstlsn, 
													 Psn2LsnP, 
													 pDev, 
													 block_size, 
													 block_num
													 );

					if(err_status != ERR_NONE)
						return err_status;

					/* invalidate old file entry. */
					err_status = DfsPlrFileEntry(entry_firstlsn, 
												 Psn2LsnP,
												 pDev, 
												 block_size, 
												 block_num
												 );

					if(err_status != ERR_NONE)
						return err_status;

					/* change entry status to ENTRY_VALID. */
					entry_status = ENTRY_VALID;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					break;

				case ENTRY_VALID:
				case ENTRY_INVALID:
					break;

				case ENTRY_WRITING:
					/* Pass through. */

				default:
					#ifdef DEBUG_FSM
					MonPrintf("File entry is in %x status "
						"in the No.%d entry of No.%d sector!\n",
						entry_status, i, Psn);
					#endif

					entry_status = ENTRY_INVALID;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					break;
				}

				if(scan_end == 1)
					break;

			} /* end for */	
		} /* end if SECTOR_TYPE_FDE*/
		else if(sector_type == SECTOR_TYPE_IDE)
		{
			hw_status = DevRead(pDev, 
								(uint8 *)&sector_status, 
								sector_address + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
								FIELD_SIZE(FsmFlashSectorHdrT, Status)
								);

			if(hw_status != HW_ERR_NONE)
				return ERR_READ;

			if(sector_status != SECTOR_VALID)
				continue;

			/* recover item entries one by one in this sector. */
			scan_end = 0;

			for(i = 0; i < item_entries; i++)
			{
				entry_address = sector_address + sizeof(FsmFlashSectorHdrT)
								+ i * sizeof(FsmItemDirEntryT);

				hw_status = DevRead(pDev, 
									(uint8 *)&entry_status, 
									entry_address + 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);

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;
				}

				switch(entry_status)
				{
				case ENTRY_EMPTY:
					scan_end = 1;
					break;

				case ENTRY_ALLOCATED:
					hw_status = DevRead(pDev, 
										(uint8 *)&entry_firstlsn, 
										entry_address + FIELD_OFFSET(FsmItemDirEntryT, FirstLsn), 
										FIELD_SIZE(FsmItemDirEntryT, FirstLsn)
										);

					if(hw_status != HW_ERR_NONE)
						return ERR_READ;

					#ifdef DEBUG_FSM
					MonPrintf("Item entry whose first lsn is %d is"
						"in ENTRY_ALLOCATED status in the No.%d entry of No.%d sector!\n",
						entry_firstlsn, i, Psn);
					#endif

					err_status = DfsPlrEntryAllocated(entry_firstlsn, 
													  Psn2LsnP,
													  pDev, 
													  block_size, 
													  block_num
													  );

					if(err_status != ERR_NONE)
						return err_status;

					entry_status = ENTRY_VALID;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					break;

				case ENTRY_DELETING:
					hw_status = DevRead(pDev, 
										(uint8 *)&entry_firstlsn, 
										entry_address + FIELD_OFFSET(FsmItemDirEntryT, FirstLsn), 
										FIELD_SIZE(FsmItemDirEntryT, FirstLsn)
										);

					if(hw_status != HW_ERR_NONE)
						return ERR_READ;

					#ifdef DEBUG_FSM
					MonPrintf("Item entry whose first lsn is %d is "
						"in ENTRY_DELETING status in the No.%d entry of No.%d sector!\n",
						entry_firstlsn, i, Psn);
					#endif

					err_status = DfsPlrEntryDeleting(entry_firstlsn, 
													 Psn,
													 (uint16)i, 
													 Psn2LsnP,
													 pDev, 
													 block_size, 
													 block_num
													 );

					if(err_status != ERR_NONE)
						return err_status;

					break;

				case ENTRY_UPDATING:
					hw_status = DevRead(pDev, 
										(uint8 *)&entry_firstlsn, 
										entry_address + FIELD_OFFSET(FsmItemDirEntryT, FirstLsn), 
										FIELD_SIZE(FsmItemDirEntryT, FirstLsn)
										);

					if(hw_status != HW_ERR_NONE)
						return ERR_READ;

					#ifdef DEBUG_FSM
					MonPrintf("Item entry whose first lsn is %d is in "
						"ENTRY_UPDATING status in the No.%d entry of No.%d sector!\n",
						entry_firstlsn, i, Psn);
					#endif

					/* recover sectors linked to this entry. */
					err_status = DfsPlrEntryUpdating(entry_firstlsn,
													 Psn2LsnP,
													 pDev, 
													 block_size,
													 block_num
													 );

					if(err_status != ERR_NONE)
						return err_status;

					/* invalidate old item entry. */
					err_status = DfsPlrItemEntry(entry_firstlsn,
												 Psn2LsnP, 
												 pDev, 
												 block_size, 
												 block_num
												 );

					if(err_status != ERR_NONE)
						return err_status;

					/* change entry status to ENTRY_VALID. */
					entry_status = ENTRY_VALID;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					break;

				case ENTRY_VALID:
				case ENTRY_INVALID:
					break;

				case ENTRY_WRITING:
					/* Pass through. */

				default:
					#ifdef DEBUG_FSM
					MonPrintf("Item entry is in %x status in the No.%d "
						"entry of No.%d sector!\n",
						entry_status, i, Psn);
					#endif

					entry_status = ENTRY_INVALID;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					break;
				}

				if(scan_end == 1)
					break;

			} /* end for */
		} /* end if SECTOR_TYPE_IDE. */
	} /* end for */

	while(*head != NULL)
	{
		Psn = (*head)->Psn;

		sector_address = DfsGetAddr(Psn, (uint16)block_sectors, block_size, sector_size);

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

		if(hw_status != HW_ERR_NONE)
			return ERR_READ;

		if((sector_status != SECTOR_VALID) && (sector_status != SECTOR_INVALID))
		{
			sector_status = SECTOR_INVALID;

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

			if(hw_status != HW_ERR_NONE)
				return ERR_WRITE;

			Psn2LsnP[Psn] = DIRTYLSN;
		}

		#ifdef DEBUG_FSM
		MonPrintf("sector (psn = %d) has been recoverd to %x status!\n", Psn, sector_status);
		#endif

		CurP  = *head;
		*head = (*head)->NextP;

		FsmFree((void *)CurP);
	}	

	for(Pbn = 0; Pbn < block_num; Pbn++)
	{
		for(i = 0; i < block_sectors; i++)
		{
			Psn = Pbn * block_sectors + i;

			Lsn = Psn2LsnP[Psn];

			if(Lsn == EMPTYLSN)
				break;
			else if(Lsn == DIRTYLSN)
				BlockStatP[Pbn].DirtySectors++;
			else
			{
				Lsn2PsnP[Lsn] = Psn;
				BlockStatP[Pbn].UsedSectors++;
			}
		}

		BlockStatP[Pbn].FreeSectors = (uint16)(block_sectors
									  - BlockStatP[Pbn].UsedSectors
									  - BlockStatP[Pbn].DirtySectors);
	}

	if(Lsn2PsnP[0] == INVALID_PSN)
	{
		uint8				find_end;
		FsmFlashSectorHdrT	sector_info;

		find_end = 0;

		for(Pbn = 0; Pbn < block_num; Pbn++)
		{
			if(Pbn == spare_blk)
				continue;

			for(i = 0; i < block_sectors; i++)
			{
				Psn = Pbn * block_sectors + i;

				if(Psn2LsnP[Psn] == EMPTYLSN)	
				{
					sector_address = DfsGetAddr(Psn, (uint16)block_sectors, block_size, sector_size);

					sector_info.Status = SECTOR_WRITING;
					sector_info.Type = SECTOR_TYPE_FDE;
					sector_info.Lsn = 0;
					sector_info.NextLsn = (uint32)(-1);

					hw_status = DevWrite(pDev, 
										 (uint8 *)&sector_info, 
										 sector_address, 
										 sizeof(FsmFlashSectorHdrT)
										 );

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					sector_status = SECTOR_ALLOCATED;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					sector_status = SECTOR_VALID;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					Lsn2PsnP[0]   = Psn;
					Psn2LsnP[Psn] = 0;

					BlockStatP[Pbn].UsedSectors++;
					BlockStatP[Pbn].FreeSectors--;

					find_end = 1;

					break;
				}
			}

			if(find_end == 1)
				break;
		}

		if(find_end == 0)
			return ERR_FULL;			
	}

	if(Lsn2PsnP[1] == INVALID_PSN)
	{
		uint8				find_end;
		FsmFlashSectorHdrT	sector_info;

		find_end = 0;

		for(Pbn = 0; Pbn < block_num; Pbn++)
		{
			if(Pbn == spare_blk)
				continue;

			for(i = 0; i < block_sectors; i++)
			{
				Psn = Pbn * block_sectors + i;

				if(Psn2LsnP[Psn] == EMPTYLSN)	
				{
					sector_address = DfsGetAddr(Psn, (uint16)block_sectors, block_size, sector_size);

					sector_info.Status = SECTOR_WRITING;
					sector_info.Type = SECTOR_TYPE_IDE;
					sector_info.Lsn = 1;
					sector_info.NextLsn = (uint32)(-1);

					hw_status = DevWrite(pDev, 
										 (uint8 *)&sector_info, 
										 sector_address, 
										 sizeof(FsmFlashSectorHdrT)
										 );

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					sector_status = SECTOR_ALLOCATED;

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

					if(hw_status != HW_ERR_NONE)
						return ERR_WRITE;

					sector_status = SECTOR_VALID;

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

					if(hw_status !=  HW_ERR_NONE)
						return ERR_WRITE;

					Lsn2PsnP[1] = Psn;
					Psn2LsnP[Psn] = 1;

					BlockStatP[Pbn].UsedSectors++;
					BlockStatP[Pbn].FreeSectors--;

					find_end = 1;

					break;
				}
			}

			if(find_end == 1)
				break;
		}

⌨️ 快捷键说明

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