📄 structuremanager.c
字号:
{
if (Root == NULL)
{
return SUCCESS;
}
OS_DRIVER_Free(Root);
return SUCCESS;
}
/*********************** ResolveConflict ***************************
* *
* Resolve the Conflict, that is two Root with same Virtual Block *
*-------------------------------------------------------------------*
* *
* *
* PARAMETER: *
* ConflictPhyBlockNum: is the physical Block Number *
* of block that has happens the *
* conflict *
* Node : Root involving in the Conflict *
* return values: *
* *
* SUCCESS:no problems is occurred *
* FAILURE:the operation is failed *
*********************************************************************/
NFTL_Return ResolveConflict(void **Node, UINT16 ConflictPhyBlockNum)
{
UINT16 ErasePhyBlockNum, PhysicalBlockNumber;
UINT8 SpareBuffer[BUFFER_SPARE_SIZE], ConfSpareBuffer[BUFFER_SPARE_SIZE];
UINT16 ConfCouter, Counter, NumPageW, ConfNumPageW, i;
UINT16 NumOfPagePerPhysicalBlock;
UINT8 flag = 0;
//Assign a value at NumberOfPagePerPhysicalBlock necessary to calculate Physical Page Address
NumOfPagePerPhysicalBlock = (32) * (512 /
CHUNK_DATA_SIZE);
if (*Node == NULL)
{
return FAILURE;
}
//initialize
NumPageW = 0;
ConfNumPageW = 0;
OS_MemSet(SpareBuffer,0xFF,BUFFER_SPARE_SIZE);
OS_MemSet(ConfSpareBuffer,0xFF,BUFFER_SPARE_SIZE);
Counter = 0;
ConfCouter = 0;
PhysicalBlockNumber = ((TreeNode *) *Node)->PhysicalBlockNumber1;
//read first spare area of Root PhysicalBlockNumber
ReadSpare528(PhysicalBlockNumber,0,SpareBuffer);
//Counter of Root
Counter = (SpareBuffer[ROOT_COUNTER_BYTE]);
//check if the first page is written
if (SpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
{
NumPageW++;
}
ReadSpare528(ConflictPhyBlockNum,0,ConfSpareBuffer);
//counter of Root that create an Conflict
ConfCouter = (ConfSpareBuffer[ROOT_COUNTER_BYTE]);
//check if the first page is written
if (ConfSpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
{
ConfNumPageW++;
}
//calculate the number of page written
for (i = 1; i < NumOfPagePerPhysicalBlock; i++)
{
ReadSpare528(ConflictPhyBlockNum,(unsigned char) i,ConfSpareBuffer) ;
if (ConfSpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
{
ConfNumPageW++;
}
else
{
break;
}
}
//calculate the number of page written
for (i = 1; i < NumOfPagePerPhysicalBlock; i++)
{
ReadSpare528(PhysicalBlockNumber,(unsigned char) i,SpareBuffer);
if (SpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
{
NumPageW++;
}
else
{
break;
}
}
if ((ConfCouter == 255) && (Counter == 0))
{
ConfCouter = 0;
Counter = 1;
}
if ((ConfCouter == 0) && (Counter == 255))
{
ConfCouter = 1;
Counter = 0;
}
//manage of conflict
if (ConfCouter > Counter)
{
if (ConfNumPageW == NumPageW)
{
//erase the leaft Left
if (EraseLeafStructure(Node) == FAILURE)
{
return FAILURE;
}
flag = 0 ;
//ErasePhyBlockNum = ((TreeNode *) *Node)->PhysicalBlockNumber1;
((TreeNode *) *Node)->PhysicalBlockNumber1 = ConflictPhyBlockNum;
}//end if( ConfNumPageW == NumPageW)
else
{
//ConfNumPageW < NumPageW
//erase block of rootConflict
flag = 1 ;
ErasePhyBlockNum = ConflictPhyBlockNum;
}
} //endif if(ConfCouter > Couter)
else
{
if (ConfNumPageW == NumPageW)
{
//erase block of rootConflict
ErasePhyBlockNum = ConflictPhyBlockNum;
flag = 1 ;
//erase the leaft Left
} //end if if( ConfNumPageW == NumPageW)
else
{
// ConfNumPageW > NumPageW
if (EraseLeafStructure(Node) == FAILURE)
{
return FAILURE;
}
flag = 0 ;
//ErasePhyBlockNum = ((TreeNode *) *Node)->PhysicalBlockNumber1;
((TreeNode *) *Node)->PhysicalBlockNumber1 = ConflictPhyBlockNum;
}
}
if (flag == 1)
{
//erase physical blck
if (BlockErase(ErasePhyBlockNum) == FAILURE)
{
//mark PhysicalBlock as bad
if (MarkBadBlock(ErasePhyBlockNum) == FAILURE)
{
return FAILURE;
}
//add in BBT store in Ram the bad block
if (AddBadBlock(ErasePhyBlockNum) == FAILURE)
{
return FAILURE;
}
}
else
{
//add block in FreeBlockChain
if (AddFreeBlock(ErasePhyBlockNum,1) == FAILURE)
{
return FAILURE;
}
}
}
return SUCCESS;
}
/********************** GetNodeByPosition ***************************
* *
* Retrieve the node of tree referred by Position *
*-------------------------------------------------------------------*
* *
* *
* PARAMETER: *
* Root: is the Root of tree *
* *
* Position: indicate the position on Node in the Tree *
* Node : is the node foundede *
* return values: *
* *
* SUCCESS:no problems is occurred *
* NODENOTFOUND:the node is not founded *
*********************************************************************/
NFTL_Return GetNodeByPosition(void *Root, UINT16 *blockNumber)
{
if (((TreeNode *) Root)->Info == 0x01)//root
{
*blockNumber = ((TreeNode *) Root)->PhysicalBlockNumber1;
return SUCCESS;
}
if (((TreeNode *) Root)->Info == 0x02)//leaf
{
*blockNumber = ((TreeNode *) Root)->PhysicalBlockNumber2;
return SUCCESS;
}
return NODENOTFOUND;
}
/********************** GetSectorOffset ****************************
* *
* Retrieve the offset value relative by Sector, *
* this information is contained into SectorMap *
*-------------------------------------------------------------------*
* *
* *
* PARAMETER: *
* PhyBlockNumber: Physical block Number *
* *
* LastWrite : indicate the last sector written *
* PhyBlockNum :Physical Block Number associated by Node *
* return values: *
* *
* SUCCESS:no problems is occurred *
* FAILURE: the operation is failed *
* PAGENOTFOUND: the sector is not written *
*********************************************************************/
NFTL_Return GetSectorOffset(SectorMap Map, UINT8 Sector, UINT8 *OffSet)
{
UINT8 CurrentOffset = 0;
INT16 Validation;
CurrentOffset = Map.Sector[Sector];
Validation = Map.OffsetValidation;
*OffSet = CurrentOffset;
if (CurrentOffset != 0)
{
return SUCCESS;
}
if ((CurrentOffset == 0) && (Validation == Sector))
{
return SUCCESS;
}
if ((CurrentOffset == 0) && (Validation != Sector))
{
return PAGENOTFOUND;
}
return FAILURE;
}
/********************** SetSectorOffset ****************************
* *
* Set the offset value relative by Sector, *
* this information is contained into SectorMap *
*-------------------------------------------------------------------*
* *
* *
* PARAMETER: *
* PhyBlockNumber: Physical block Number *
* *
* LastWrite : indicate the last sector written *
* PhyBlockNum :Physical Block Number associated by Node *
* return values: *
* *
* SUCCESS:no problems is occurred *
* FAILURE: the operation is failed *
* PAGENOTFOUND: the sector is not written *
*********************************************************************/
NFTL_Return SetSectorOffset(INT32 Map, UINT8 Sector, UINT8 OffSet)
{
SetSMSectorElement(Map,Sector,OffSet);
if (OffSet == 0x00)
{
SetSMOffsetValidation(Map,Sector);
} //Map.OffsetValidation=Sector;
return SUCCESS;
}
/********************** CreateSectorMap ****************************
* *
* Read the spare area of physical block referred *
* by PhysicalBlockNumber and build SecrorMap *
* *
*-------------------------------------------------------------------*
* *
* PARAMETER: *
* PhyBlockNumber: Physical block Number *
* *
* Map : SectorMap *
* *
* return values: *
* *
* SUCCESS:no problems is occurred *
* FAILURE: the operation is failed *
*********************************************************************/
NFTL_Return CreateSectorMap(UINT16 PhysicalBlockNumber, SectorMap *Map, UINT8 *LastWrite)
{
UINT8 SectorNumber;
UINT8 SpareBuffer[BUFFER_SPARE_SIZE];
UINT8 lastPage = 0;
INT8 i;
//OS_MemSet(Map->Sector,0x00,MAX_SECTOR_NUMBER);
{
UINT8 *pSector = Map->Sector ;
for (i =0 ;i<32 ;i+=16)
{
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
*pSector++=0 ;
}
}
Map->OffsetValidation = -1;
Map->PhysicalBlockNumber = PhysicalBlockNumber;
// EnableNAND();
for (i = 0; i < 32; i++)
{
UINT32 returnAddress;
returnAddress =mCalculateAddress(PhysicalBlockNumber,i);
NAND_SpareReadRandom(returnAddress,SpareBuffer,CHUNK_SPARE_SIZE) ;
if (SpareBuffer[PAGE_STATUS_BYTE] == WRITTEN)
{
SectorNumber = SpareBuffer[SECTOR_NUMBER] | SpareBuffer[COPY_SECTOR_NUMBER];
if (i == 0)
{
Map->OffsetValidation = SectorNumber;
}
Map->Sector[SectorNumber] = i;
lastPage++;
}
else
{
break;
}
}
//DisableNAND();
if (lastPage == 0)
{
*LastWrite = 255;
}
else
{
*LastWrite = lastPage - 1;
}
return SUCCESS;
}
/********************** CopySectorMap *****************************
* *
* Copy Origin SectorMap in Destination SectorMap *
* *
*-------------------------------------------------------------------*
* *
* PARAMETER: *
* PhyBlockNumber: Physical block Number *
* *
* Origin : SectorMap *
* Destination : SectorMap *
* *
* return values: *
* *
* SUCCESS:no problems is occurred *
* FAILURE: the operation is failed *
*********************************************************************/
#if 0
NFTL_Return CopySectorMap(SectorMap Origin, INT32 Destination)
{
UINT8 i;
SetSMCachePhysicalBlockNumber(Destination,Origin.PhysicalBlockNumber);
SetSMOffsetValidation(Destination,Origin.OffsetValidation);
for (i = 0; i < MAX_SECTOR_NUMBER; i+=16)
{
Cache[Destination].Sector[i] = Origin.Sector[i];
Cache[Destination].Sector[i+1] = Origin.Sector[i+1];
Cache[Destination].Sector[i+2] = Origin.Sector[i+2];
Cache[Destination].Sector[i+3] = Origin.Sector[i+3];
Cache[Destination].Sector[i+4] = Origin.Sector[i+4];
Cache[Destination].Sector[i+5] = Origin.Sector[i+5];
Cache[Destination].Sector[i+6] = Origin.Sector[i+6];
Cache[Destination].Sector[i+7] = Origin.Sector[i+7];
Cache[Destination].Sector[i+8] = Origin.Sector[i+8];
Cache[Destination].Sector[i+9] = Origin.Sector[i+9];
Cache[Destination].Sector[i+10] = Origin.Sector[i+10];
Cache[Destination].Sector[i+11] = Origin.Sector[i+11];
Cache[Destination].Sector[i+12] = Origin.Sector[i+12];
Cache[Destination].Sector[i+13] = Origin.Sector[i+13];
Cache[Destination].Sector[i+14] = Origin.Sector[i+14];
Cache[Destination].Sector[i+15] = Origin.Sector[i+15];
}
return SUCCESS;
}
#endif
NFTL_Return CopySectorMap(SectorMap Origin, INT32 Destination)
{
UINT8 i;
UINT8 *pDst, *pSrc ;
SetSMCachePhysicalBlockNumber(Destination,Origin.PhysicalBlockNumber);
SetSMOffsetValidation(Destination,Origin.OffsetValidation);
pDst=&(Cache[Destination].Sector[0]);
pSrc=&(Origin.Sector[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -