📄 reclaim.c
字号:
/* loop through all blocks in component and pick block with the most
VSBs discarded to reclaim. */
do
{
/* ignore spare block */
if( BlockCount != SpareBlock[ComponentID] )
{
/* get physical adress of top of block */
RecoverAddr = CalculateFlashAddr( ComponentID, BlockCount, 0 );
RecoverAddr += sizeof( WORD ); /* point to first VAT entry */
VSBCount = 1;
do
{
/* read VAT entry */
if ((RetVal = FlashDevRead(RecoverAddr, sizeof(WORD), (BYTE *)&RecoverData))
!= ERR_NONE)
return (RetVal);
if( (RecoverData & VSB_DISCARD_MASK) == 0 ) /* discarded */
{
++ReclaimCount; /* increment discard count */
}
RecoverAddr += sizeof( WORD ); /* point to nex VAT entry */
/*E2.3.41, Added -(VAT_SIZE_VSB-1) after VSB_PER_BLOCK*/
} while( ++VSBCount < (VSB_PER_BLOCK -(VAT_SIZE_VSB-1)));
if( ReclaimCount > DiscardCount ) /* found a bigger disacrd count */
{
DiscardCount = ReclaimCount; /* save lager discard count */
RecoverBlock = BlockCount; /* save block number */
}
ReclaimCount = 0; /* re-init discard count */
}
} while( ++BlockCount < BLOCK_COUNT );
if( DiscardCount == 0 ) /* any discarded VSBs found? */
{
if(status_ptr->clean_sectors == 0)
return( ERR_MEMORY_FULL ); /* nothing to do(memory full) */
/*E2.3.23, added && (status_ptr->dirty_sectors != 0)*/
else if((ReclaimThresholdOverride == FALSE) && (status_ptr->dirty_sectors != 0))
return( ERR_MEMORY_FULL ); /* nothing to do(memory full) */
else return ( ERR_NONE ); /* nothing to do(memory empty) */
}
else if( ((DiscardCount + status_ptr->clean_sectors)
< RECLAIM_THRESHOLD) && (ReclaimThresholdOverride == FALSE) )
return ( ERR_MEMORY_FULL );
if( RetVal == ERR_NONE )
{
ReclaimBlock = SpareBlock[ComponentID]; /* setp block to reclaim into */
ReclaimAddr = CalculateFlashAddr( ComponentID,/* get physical address */
ReclaimBlock, /* of block to reclaim */
VSB_FB_ATTR ); /* into */
BlockData = VSB_FB_RECOVER;
#if PLR_TESTING
if (PowerLossFlags.breakpoint_number == PLR_BP8)
PowerLossFlags.current_iteration++;
#endif
RetVal = FlashDevWrite( ReclaimAddr, /* write reclaiming */
sizeof( BYTE ), /* block attribute */
&BlockData );
}
if( RetVal == ERR_NONE )
{
/* init recliam loop variables */
ReclaimCount = 1;
RecoverCount = 1;
VSBCount = 1;
/* loop through all VSB in recover block, copying valid VSBs */
/* to reclaim block */
do
{
/* get physical address of recover block */
RecoverAddr = CalculateFlashAddr( ComponentID, RecoverBlock,
RecoverCount * VAT_ENTRY_SIZE );
/* read VAT entry */
if ((RetVal = FlashDevRead(RecoverAddr, VAT_ENTRY_SIZE, (BYTE *)&RecoverData))
!= ERR_NONE)
return (RetVal);
/* VAT discarded? or free? */
if( (RecoverData & VSB_DISCARD_MASK) == 0 || RecoverData == VSB_FREE )
{
++RecoverCount; /* yep, next VAT entry */
continue;
}
else
{
/* get physical address of reclaim block */
ReclaimAddr = CalculateFlashAddr( ComponentID, ReclaimBlock,
ReclaimCount * VAT_ENTRY_SIZE );
/* write recovered VAT entry */
#if PLR_TESTING
if (PowerLossFlags.breakpoint_number == PLR_BP9)
PowerLossFlags.current_iteration++;
#endif
RetVal = FlashDevWrite( ReclaimAddr, VAT_ENTRY_SIZE,
(BYTE *)&RecoverData );
if( RetVal == ERR_NONE )
{
/* copy from recover block to reclaim block */
/* conforming to API -cnc */
/*Comment-, Changed here for E2.3.41 as MoveVSB has not been changed,
it has not been changed there as some call use CurrentVSB that is changed in FindVSB*/
/*E2.3.41 Changed RetVal = MoveVSB(CalculateFlashAddr(ComponentID, ReclaimBlock,
(ReclaimCount*VSB_SIZE)), MOVE_FLASH,
CalculateFlashAddr(ComponentID, RecoverBlock,
(RecoverCount*VSB_SIZE)), MOVE_FLASH, (WORD)VSB_SIZE);
to */
RetVal = MoveVSB(CalculateFlashAddr(ComponentID, ReclaimBlock,
((ReclaimCount+(VAT_SIZE_VSB-1)) * VSB_SIZE)), MOVE_FLASH,
CalculateFlashAddr(ComponentID, RecoverBlock,
((RecoverCount+(VAT_SIZE_VSB-1)) * VSB_SIZE)), MOVE_FLASH, (WORD)VSB_SIZE);
}
else
RetVal = ERR_WRITE;
if( RetVal != ERR_NONE )
{
/* bail if error occured */
break;
}
/* next recover VAT entry */
++RecoverCount;
/* next reclaim VAT entry */
++ReclaimCount;
}
} while( ++VSBCount < (VSB_PER_BLOCK -(VAT_SIZE_VSB-1)));
}
if( RetVal == ERR_NONE )
{
ReclaimAddr = CalculateFlashAddr( ComponentID,/* get physical address */
ReclaimBlock, /* of reclaim block */
VSB_FB_ATTR + 1 );
#if PLR_TESTING
if (PowerLossFlags.breakpoint_number == PLR_BP10)
PowerLossFlags.current_iteration++;
#endif
/* write recover block number */
RetVal = FlashDevWrite( ReclaimAddr, sizeof( BYTE ), &RecoverBlock );
if( RetVal == ERR_NONE )
{
--ReclaimAddr; /* point to block attribute */
if( (FlashDevRead( ReclaimAddr, /* Read block status to be */
sizeof( BYTE ), /* marked as erasing another */
&BlockData )) == ERR_NONE )
BlockData &= VSB_FB_ERASING;
/* mark block as erasing another */
#if PLR_TESTING
if (PowerLossFlags.breakpoint_number == PLR_BP11)
PowerLossFlags.current_iteration++;
#endif
RetVal = FlashDevWrite( ReclaimAddr, sizeof( BYTE ), &BlockData );
}
else
RetVal = ERR_WRITE;
if( RetVal == ERR_NONE )
{
/* get physical address of recover block */
RecoverAddr = CalculateFlashAddr( ComponentID, RecoverBlock, 0 );
status_ptr->clean_sectors=status_ptr->clean_sectors+DiscardCount;
status_ptr->dirty_sectors=status_ptr->dirty_sectors-DiscardCount;
RetVal = FlashDevEraseBlock( RecoverAddr ); /* erase recover block */
if( RetVal == ERR_NONE )
{
SpareBlock[ComponentID] = RecoverBlock; /* spare = recover */
}
else
RetVal = ERR_ERASE;
}
}
if( RetVal == ERR_NONE )
{
CurrentBlock[ComponentID] = ReclaimBlock; /* also current block */
ReclaimAddr = CalculateFlashAddr( ComponentID,/* get physical address */
ReclaimBlock, /* of reclaim block */
VSB_FB_ATTR );
BlockData = VSB_FB_WRITE;
/* mark reclaim block as write block */
#if PLR_TESTING
if (PowerLossFlags.breakpoint_number == PLR_BP12)
PowerLossFlags.current_iteration++;
#endif
RetVal = FlashDevWrite( ReclaimAddr, sizeof( BYTE ), &BlockData );
if( RetVal != ERR_NONE )
RetVal = ERR_WRITE;
}
return( RetVal );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -