📄 fsmrecl.c
字号:
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsReclaimThisBlock(),FsmDevWrite Failed.");
#endif
return status;
}
/* Get Reclaimed Block Info Address */
ReclaimedAddr = ReclaimedBlockAddr + BlockSize - sizeof(FsmBlockInfoT);
/* Write invalid FSMTAG to Reclaimed Block */
FsmTag = 0;
status = pDrv->FsmDevWrite( DevObjP,
(uint8 *)&FsmTag,
ReclaimedAddr + FIELD_OFFSET(FsmBlockInfoT, Tag),
FIELD_SIZE(FsmBlockInfoT, Tag)
);
/* Error checking is ignored. */
/* Begin Erasing */
status = pDrv->FsmDevErase(DevObjP, ReclaimedBlockAddr);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsReclaimThisBlock(),FsmDevErase Failed.");
#endif
return status;
}
/* Erased */
/* The Reclaimed Block Status is now BLK_ERASED */
/* Write (EraseCount + 1) back to Reclaimed Block */
/*
EraseCount++;
*/
status = pDrv->FsmDevWrite( DevObjP,
(uint8 *)&EraseCount,
ReclaimedAddr + FIELD_OFFSET(FsmBlockInfoT, EraseCount),
FIELD_SIZE(FsmBlockInfoT, EraseCount)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsReclaimThisBlock(),FsmDevWrite Failed.");
#endif
return status;
}
/* Write FSMTAG to Reclaimed Block */
FsmTag = FSM_TAG;
status = pDrv->FsmDevWrite( DevObjP,
(uint8 *)&FsmTag,
ReclaimedAddr + FIELD_OFFSET(FsmBlockInfoT, Tag),
FIELD_SIZE(FsmBlockInfoT, Tag)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsReclaimThisBlock(),FsmDevWrite FSMTAG Failed.");
#endif
return status;
}
/* Valid */
/* Set SpareBlock Status to BLK_VALID */
BlockStatus = BLOCK_VALID;
status = pDrv->FsmDevWrite( DevObjP,
(uint8 *)&BlockStatus,
BlockInfoAddr + FIELD_OFFSET(FsmBlockInfoT, Status),
FIELD_SIZE(FsmBlockInfoT, Status)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsReclaimThisBlock(),FsmDevWrite Block Status Failed.");
#endif
return status;
}
if((status = FsmGetMtxSem(MediaP->InfoLock)) != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsReclaimThisBlock(),Sem (DevInfoLock) Obtained Failed.");
#endif
return status;
}
/* Update The Flash Info of SpareBlock, Perhaps No use */
MediaP->BlockInfoP[SpareBlockPbn].UsedSectors += SectorIndex;
MediaP->BlockInfoP[SpareBlockPbn].FreeSectors -= SectorIndex;
/* Update The Flash Info of Reclaimed Block, Perhaps No use */
MediaP->BlockInfoP[ReclaimedPbn].FreeSectors = SectorsPerBlk;
MediaP->BlockInfoP[ReclaimedPbn].UsedSectors = 0;
MediaP->BlockInfoP[ReclaimedPbn].DirtySectors = 0;
/*
MediaP->BlockInfoP[ReclaimedPbn].EraseCount++;
*/
/* Update the SpareBlk. Now, It pointed to the Reclaimed block. */
MediaP->SpareBlk = ReclaimedPbn;
/* Release InfoLock */
FsmReleaseMtxSem(MediaP->InfoLock);
#ifdef DEBUG_FSM
End_Time = FsmGetCurrentTime();
Execute_Time = (End_Time - Start_Time);
MonPrintf("\n Reclaim Block Execute Time is %d",Execute_Time);
#endif
return ERR_NONE;
}
/*********************************************************************************************
*
* Function Name: DfsCopySectorValidData(FsmMediaObjHdrT *pDevHdr,uint32 DestAddr,uint32 SrcAddr)
* Description:
* Copy Sector valid data of Reclaimed block to Spare block, when reclaimation.
* When DEBUG_FSM, print total running time of copying one sector valid data.
* Input:
* SrcAddr: Address of sector which valid data need to be copied out(Include SectorHdr).
* DestAddr: Address of sector into which will be copied valid data.(Include SectorHdr)
* That is,the addrs,either SrcAddr or DestAddr, are all sectorHdr Start Addr.
* FsmMediaObjHdrT *pDevHdr: the Falsh device structure,which need to be reclaimed.
* Output:
* N/A
* Return:
* 0 or ErrorCode
* Comment:
* There is no lock internally, and does not need lock externally too.
* Copy Sector Valid Data to Spare Block,especially the dir entry sector
*
***********************************************************************************************/
static uint32 DfsCopySectorValidData(FsmDevObjHdrT * DevObjP, uint32 DestAddr, uint32 SrcAddr)
{
uint32 status;
uint32 i;
uint16 SectorType;
uint32 SectorSize;
uint16 EntryStatus;
uint16 EntriesPerSector;
uint16 InstanceStatus;
uint16 InstanceLength;
FsmFlashMediaT * MediaP;
FsmDevDrvT * pDrv;
#ifdef DEBUG_FSM
uint32 Start_Time,End_Time,Execute_Time;
Start_Time = FsmGetCurrentTime();
#endif
pDrv = DevObjP->DevDrvP;
MediaP = DevObjP->MediaObjP;
if(MediaP == NULL)
{
return ERR_PARAM;
}
SectorSize = MediaP->SectorSize;
/* Get Sector Type */
status = pDrv->FsmDevRead(DevObjP,
(uint8 *)&SectorType,
SrcAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Type),
FIELD_SIZE(FsmFlashSectorHdrT, Type)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevRead Failed.");
#endif
return status;
}
/* File Directory Entry Sector */
if((SectorType == SECTOR_TYPE_FDE) || (SectorType == SECTOR_TYPE_IDE))
{
uint16 EntrySize;
uint16 offset;
uint16 size;
if(SectorType == SECTOR_TYPE_IDE)
{
EntrySize = sizeof(FsmItemDirEntryT);
offset = FIELD_OFFSET(FsmItemDirEntryT, Status);
size = FIELD_SIZE(FsmItemDirEntryT, Status);
}
else
{
EntrySize = sizeof(FsmFileDirEntryT);
offset = FIELD_OFFSET(FsmFileDirEntryT, Status);
size = FIELD_SIZE(FsmFileDirEntryT, Status);
}
EntriesPerSector = (uint16)(SectorSize / EntrySize);
/* Copy Sector Header to Destination */
status = pDrv->FsmDevCopy(DevObjP, DestAddr, SrcAddr, sizeof(FsmFlashSectorHdrT));
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevCopy Failed.");
#endif
return status;
}
SrcAddr += sizeof(FsmFlashSectorHdrT);
DestAddr += sizeof(FsmFlashSectorHdrT);
for(i = 0; i< EntriesPerSector; i++, SrcAddr += EntrySize)
{
/* Get Entry Status */
status = pDrv->FsmDevRead(DevObjP,
(uint8 *)&EntryStatus,
SrcAddr + offset,
size
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevRead Failed.");
#endif
return status;
}
if(EntryStatus != ENTRY_VALID)
continue;
/* Copy Valid Entry to Destination */
status = pDrv->FsmDevCopy(DevObjP,
DestAddr,
SrcAddr,
EntrySize
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevCopy Failed.");
#endif
return status;
}
DestAddr += EntrySize;
}
}
/* Multi-Instance Sector used for data item*/
else if(SectorType == SECTOR_TYPE_MID)
{
uint32 Instances;
uint32 InstIndex;
/* Copy Sector Header to Destination */
status = pDrv->FsmDevCopy(DevObjP, DestAddr, SrcAddr, sizeof(FsmFlashSectorHdrT));
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevCopy SectorHdr Failed.");
#endif
return status;
}
SrcAddr += sizeof(FsmFlashSectorHdrT);
DestAddr += sizeof(FsmFlashSectorHdrT);
/* Get Instance Length */
status = pDrv->FsmDevRead(DevObjP,
(uint8 *)&InstanceLength,
SrcAddr + FIELD_OFFSET(FsmMultiInstanceT, Length),
FIELD_SIZE(FsmMultiInstanceT, Length)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevRead Instance len Failed.");
#endif
return status;
}
/* Set Instance Length */
status = pDrv->FsmDevWrite(DevObjP,
(uint8 *)&InstanceLength,
DestAddr + FIELD_OFFSET(FsmMultiInstanceT, Length),
FIELD_SIZE(FsmMultiInstanceT, Length)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevWrite Instance len Failed.");
#endif
return status;
}
Instances = SectorSize - FIELD_SIZE(FsmMultiInstanceT, Length);
Instances = Instances / (FIELD_SIZE(FsmMultiInstanceT, Status) + InstanceLength);
InstIndex = 0;
while (InstIndex < Instances)
{
InstanceStatus = 0;
status = pDrv->FsmDevRead(DevObjP,
(uint8 *)&InstanceStatus,
SrcAddr + FIELD_OFFSET(FsmMultiInstanceT, Status[0])
+ InstIndex * FIELD_SIZE(FsmMultiInstanceT, Status),
FIELD_SIZE(FsmMultiInstanceT, Status)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevRead Instance Status Failed.");
#endif
return status;
}
if (InstanceStatus == INSTANCE_VALID)
{
break;
}
InstIndex++;
}
if (InstIndex >= Instances)
return ERR_SYSTEM;
/* New instance status. */
InstanceStatus = INSTANCE_VALID;
status = pDrv->FsmDevWrite(DevObjP,
(uint8 *)&InstanceStatus,
DestAddr + FIELD_OFFSET(FsmMultiInstanceT, Status[0]),
FIELD_SIZE(FsmMultiInstanceT, Status[0])
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevWrite Instance status Failed.");
#endif
return status;
}
SrcAddr += FIELD_SIZE(FsmMultiInstanceT, Length);
DestAddr += FIELD_SIZE(FsmMultiInstanceT, Length);
SrcAddr += Instances * FIELD_SIZE(FsmMultiInstanceT, Status[0]);
DestAddr += Instances * FIELD_SIZE(FsmMultiInstanceT, Status[0]);
SrcAddr += InstIndex * InstanceLength;
status = pDrv->FsmDevCopy(DevObjP,
DestAddr,
SrcAddr,
InstanceLength
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevCopy Instance Failed.");
#endif
return status;
}
}
/* Single-Instance Data Sector */
else
{
/* Copy SectorHdr and SectorContent to Dest */
status = pDrv->FsmDevCopy(DevObjP,
DestAddr,
SrcAddr,
SectorSize + sizeof(FsmFlashSectorHdrT)
);
if(status != ERR_NONE)
{
#ifdef DEBUG_FSM
MonPrintf("\n In DfsCopySectorValidData(),FsmDevCopy single-instance Data Failed.");
#endif
return status;
}
}
#ifdef DEBUG_FSM
End_Time = FsmGetCurrentTime();
Execute_Time = (Start_Time - End_Time);
// MonPrintf("\n Execute Time is %d",Execute_Time);
#endif
return ERR_NONE;
}
/*****************************************************************************
* $Log: FsmRecl.c $
* Revision 1.3 2004/03/17 12:57:35 zgy
* Revision 1.25 2004/03/16 15:54:45 jjs
* Revision 1.24 2004/03/11 15:16:25 jjs
* Revision 1.23 2003/11/25 14:15:40 wangli
* Get InfoLock When update Block_EraseCount in DfsReclaimProcess. It is not affirmative ! ! !
* Revision 1.22 2003/11/25 14:03:58 wangli
* Add Macro WEARING_LEVEL_INCREMENT for Reclaimation
* Revision 1.21 2003/10/14 19:05:24 jjs
* Revision 1.20 2003/10/14 18:55:32 jjs
* Fix bugs in multi-instance copy.
* Revision 1.19 2003/10/14 14:41:57 jjs
* Revision 1.18 2003/10/14 11:11:05 jjs
* Revision 1.17 2003/10/09 16:30:30 wangli
* Revision 1.16 2003/09/19 10:23:23 wangli
* delete some no use operations
* Revision 1.15 2003/09/19 09:53:06 wangli
* Update Lsn2PsnMapTable when every copy ending
* Revision 1.14 2003/09/16 22:08:22 wangli
* change InsanceLength from uint32 to uint16
* Revision 1.13 2003/09/16 20:20:22 wangli
* Revision 1.12 2003/09/16 20:00:20 wangli
* Revision 1.11 2003/09/16 18:20:32 wangli
* Revision 1.10 2003/09/16 08:47:17 wangli
* Revision 1.9 2003/09/15 20:47:17 wangli
* Revision 1.8 2003/09/15 19:13:45 wangli
* abolish the macro MULTI_INSTANCE
* Revision 1.7 2003/09/15 09:15:36 wangli
* data type of Pbn changed from uint32 to uint16
* Revision 1.6 2003/09/14 16:57:32 jjs
* Revision 1.5 2003/09/12 16:34:52 wangli
* Revision 1.4 2003/09/12 15:44:33 wangli
* Modify Function Name and Return Data Type
* Revision 1.3 2003/09/12 11:35:15 wangli
* Modify Some faults
* Revision 1.2 2003/09/10 16:00:04 wangli
* Merge First Time, update according to code criterion
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -