📄 matchalg.c
字号:
/* Unit Found */
*wLogicalUnit = MATCH_VARS->lookUpTable.logicalUnit[i>>MTD_VARS->bNoOfPlanesBits] ;
return TRUE ;
}
}
}
/*** If we got here we searched the whole table and no this physical ***/
/*** unit was not found ***/
return FALSE ;
}
#endif /* HW_PROTECTION */
/************************************************************************
* Name : MATCH_printLOOKUP_Table ()
* print the Lookup Table
*
* Parameters:
* flashPtr : The flash struct.
* wPhyUnit : Physical unit to search
*
* Returns :
* TRUE : The Physical unit was found in the table
* FALSE: The Physical unit was not found in the table.
* wLogicalUnit : If the Physical Unit was found the routine would
* return the Logical unit as an output
************************************************************************/
#ifdef DEBUG_MTD
void MATCH_printLOOKUP_Table (FLFlash *flashPtr)
{
FLDword i ;
FLByte j ;
DBG_PRINT_WRN(FLZONE_MTD,("************************************************\r\n")) ;
for (i=0;i<MATCH_VARS->lookUpTable.dwTableSize;i++)
{
DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT("Logical=0x%lx"),MATCH_VARS->lookUpTable.logicalUnit[i])) ;
DBG_PRINT_WRN (FLZONE_MTD,"\tPhysical=") ;
for(j = 0 ; j < flashPtr->noOfPlanes ; j++)
{
DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT("%x\t")
,MATCH_VARS->lookUpTable.physicalUnit[(i<<MTD_VARS->bNoOfPlanesBits)+j]))
}
DBG_PRINT_WRN (FLZONE_MTD,"\r\n") ;
}
DBG_PRINT_WRN (FLZONE_MTD,"************************************************\r\n") ;
}
#endif
/********************* Waiting to be matched table routines *************/
/************************************************************************/
/************************************************************************
* Name : MATCH_waitingToBeMatched_Add ()
* Add Physical units to the waiting to be matched table
*
* Parameters:
* flashPtr : The flash struct.
* wPhyUnit : Physical unit to add
************************************************************************/
void MATCH_waitingToBeMatched_Add(FLFlash *flashPtr,PhyUnitType wPhyUnit)
{
if(MATCH_VARS->waitingToBeMatched.noOfUnits < WAIT_TO_BE_MATCHED_SIZE)
{
MATCH_VARS->waitingToBeMatched.physicalUnit[MATCH_VARS->waitingToBeMatched.noOfUnits]=wPhyUnit;
MATCH_VARS->waitingToBeMatched.noOfUnits++ ;
}
}
/************************************************************************
* Name : MATCH_waitingToBeMatched_Remove ()
* Remove no of planes Physical units from the waiting to be matched table
*
* Note: The Physical units given must be in the table.
*
* Parameters:
* flashPtr : The flash struct.
* wPhyUnitsArray : Array that holds the number of physical units needs
* to be entered to the waiting to be matched table
************************************************************************/
static void MATCH_waitingToBeMatched_Remove (FLFlash *flashPtr,
PhyUnitType *wPhyUnitsArray)
{
FLWord i,j;
/* First find the location of the Phy unit that needs to be removed */
for (j=flashPtr->noOfPlanes;j>0;j--)
{
for (i=0;MATCH_VARS->waitingToBeMatched.physicalUnit[i]!=*wPhyUnitsArray;i++);
/* Now in WAITING_TO_BE_MATCHED.PhysicalUnit[i] we have the item we want to remove
we will remove it by swapping with the last item and reducing the table size by 1 */
MATCH_VARS->waitingToBeMatched.noOfUnits-- ;
MATCH_Swap(MATCH_VARS->waitingToBeMatched.physicalUnit[i],MATCH_VARS->waitingToBeMatched.physicalUnit[MATCH_VARS->waitingToBeMatched.noOfUnits]) ;
wPhyUnitsArray++ ;
}
}
/************************************************************************
* Name : MATCH_waitingToBeMatched_EraseAllItems ()
* Erase all items in the waiting to be matched table (Initialize it)
*
* Parameters:
* flashPtr: The flash struct.
************************************************************************/
void MATCH_waitingToBeMatched_EraseAllItems(FLFlash * flashPtr)
{
MATCH_VARS->waitingToBeMatched.noOfUnits = 0 ;
MATCH_VARS->waitingToBeMatched.wPlaneArrayIndex = INVALID_PLANE_ARRAY_INDEX;
}
#ifdef DEBUG_MTD
/************************************************************************
* Name : MATCH_waitingToBeMatched_Print ()
* Print the waiting to be matched table
*
* Parameters:
* flashPtr: The flash struct.
* Returns :
*
************************************************************************/
static void MATCH_waitingToBeMatched_Print (FLFlash * flashPtr)
{
FLWord i;
for (i=0;i<MATCH_VARS->waitingToBeMatched.noOfUnits;i++)
DBG_PRINT_ERR_PRM(FLZONE_MTD,(FLTXT("0x%x "),MATCH_VARS->waitingToBeMatched.physicalUnit[i]));
DBG_PRINT_ERR(FLZONE_MTD,"\r\n") ;
}
#endif /* DEBUG_MTD */
/************************************************************************
* Name : MATCH_InitFirstAvailLogicalUnitTable
* Initalizes the MATCH_VARS->FirstAvailUnitTable table array
* The structure of this table is:
* MATCH_VARS->FirstAvailUnitTable[x] : Holds the First Logical
* Available unit in floor x
*
* - The value is the first logical unit after the media header
* Logical unit is available if :
* - This unit is not ASIC dedicated unit.
* - This unit does not hold the media header.
* Parameters:
* flashPtr: The flash struct.
* Returns :
* MATCH_VARS->FirstAvailUnitTable : The first available unit of each floor
* flOK on success.
* flGeneralFailure in case no good unit ws found on one of the floors.
************************************************************************/
FLStatus MATCH_InitFirstAvailLogicalUnitTable (FLFlash *flashPtr)
{
FLByte bFloor ;
FLByte bGoodLogicalUnitsFound ;
FLBoolean fAllUnitAreGood,fisGoodBlock ;
FLWord wUnit,i,j ;
MTDArgumentPacket *argsPackPtr ;
FLDword dwPhyUnitArray[MAX_NUMBER_OF_PLANES];
argsPackPtr = &flashPtr->args ;
for (bFloor=0;bFloor<flashPtr->noOfFloors;bFloor++)
{
/* The First units are used for saving the OTP,DPS0,DPS1 & IPL
so we need to find the first logical unit to work with.
the MTD_VARS->FirstUsableBlock holds the First physical block which can
be used for TL use => we would Find the simple logical unit that it belongs to */
wUnit = (MTD_VARS->FirstUsableBlock[bFloor] + flashPtr->noOfPlanes - 1)>>
MTD_VARS->bNoOfPlanesBits ; /* Round up */
/* Add the floor offset to the FirstUsableBlock by the ASIC */
wUnit += (FLWord)(bFloor*MTD_VARS->dwLogicalUnitsInFloor) ;
for(bGoodLogicalUnitsFound = 0 , j = 0;
bGoodLogicalUnitsFound<argsPackPtr->noOfSkippedUnits;j++)
{
/* Find the Physical unit using a simple mathematical rule */
for (i=0;i<flashPtr->noOfPlanes;i++)
dwPhyUnitArray[i]=(wUnit<<MTD_VARS->bNoOfPlanesBits)+i ;
/* Check if one of these physical units is bad block */
fAllUnitAreGood = TRUE ;
for (i=0;i<flashPtr->noOfPlanes;i++)
{
checkStatus(MTD_VARS->isGoodBlock (flashPtr,dwPhyUnitArray[i],USE_BBT_CACHE,&fisGoodBlock));
if (fisGoodBlock == FALSE)
fAllUnitAreGood = FALSE ;
}
if (fAllUnitAreGood==TRUE)
bGoodLogicalUnitsFound++ ;
wUnit++ ;
if(j>MAX_GOOD_BLOCKS_SEARCH)
{
DBG_PRINT_ERR(FLZONE_MTD,"ERROR in InitFirstAvailLogicalUnitTable:No place for media header in floor zero.\r\n") ;
return flGeneralFailure;
}
}
MATCH_VARS->FirstAvailUnitTable[bFloor] = wUnit ;
}
return flOK;
}
/************************************************************************
* Name : MATCH_IsLogicalUnitAvailable
* Logical unit is available if the two coditions are true ::
* - This unit is one of the units dedicated for the ASIC
* - This unit is not one of the skipped units (media header)
*
* Note : InitFirstAvailLogicalUnitTable must be called prior to calling
* this macro.
*
* Parameters:
* flashPtr: The flash struct.
* wUnit: The unit that needs to be checked
*
* Returns :
* 1 : LogicalUnit is available
* 0 : Logical unit is unavailable
************************************************************************/
#define MATCH_IsLogicalUnitAvailable(flashPtr,wUnit) \
(wUnit>=MATCH_VARS->FirstAvailUnitTable[wUnit / MTD_VARS->dwLogicalUnitsInFloor])
/************************************************************************
* Name : MATCH_PerformMatchingAlgorithm ()
* Perform the matching algorithm in a specific partition.
*
* Parameters:
* flashPtr: The flash struct.
* dwOpAlgorithm: MTD_SM - Simple Matching algorithm.
* MTD_AM - Advanced Matching algorithm.
* wNoOfUnits: Number of required good logical units.
* wFirstUnit: The First Logical unit that the partition starts from
*
* Returns:
* wLastUnit : The Last Logical unit that the partition ends in.
* Valid only if matching is possible
* wNoOfUnitsMatched : Returns the Number of logical good units found
* In case that the matching succeeded it should be the same as NoOfUnits.
* In case that matching failed it returns the number of logical good units
* that the routine found (NoOfUnitsMatched < NoOfUnits).
* flOK om success , any other value on failure.
************************************************************************/
static FLStatus MATCH_PerformMatchingAlgorithm (FLFlash * flashPtr,
FLDword dwOpAlgorithm,
FLWord wNoOfUnits,
LogicUnitType wFirstUnit,
LogicUnitType *wLastUnitPtr,
LogicUnitType *wNoOfUnitsMatched,
FLBoolean AddToLookUpTable)
{
LogicUnitType wUnit ;
FLDword dwPhyUnitArray[MAX_NUMBER_OF_PLANES];
FLDword dwLogicalUnitsInPlaneArray ;
FLBoolean fAllUnitAreGood,fFoundMatchInTable,fUnitInPlaneWasFound,fMATCH_isGoodBlock ;
PhyUnitType wPhyUnitReadFromTable[MAX_NUMBER_OF_PLANES] ;
FLWord i,j ;
MATCH_waitingToBeMatched_EraseAllItems (flashPtr) ;
*wNoOfUnitsMatched = 0;
dwLogicalUnitsInPlaneArray = MTD_VARS->wUnitsInChip / (MTD_VARS->bPlaneArraysInChip<<MTD_VARS->bNoOfPlanesBits) ;
for (wUnit=wFirstUnit;wUnit<MTD_VARS->dwLogicalUnitsInPlatform;wUnit++)
{
if (!MATCH_IsLogicalUnitAvailable(flashPtr,wUnit))
{ /* This unit is unavailable (ASIC dedicated units or media header units) */
continue ;
}
/* Check if one of these physical units is bad block */
fAllUnitAreGood = TRUE ;
for (i=0;i<flashPtr->noOfPlanes;i++)
{
/* Find the Physical units of the Logical unit using mathematical formula */
dwPhyUnitArray[i]=(wUnit<<MTD_VARS->bNoOfPlanesBits)+i ;
/* Check if unit is good */
checkStatus(MTD_VARS->isGoodBlock (flashPtr,dwPhyUnitArray[i],USE_BBT_CACHE,&fMATCH_isGoodBlock));
if (fMATCH_isGoodBlock==FALSE)
{
dwPhyUnitArray[i] = PHYSICAL_BLOCK_IS_BAD;
fAllUnitAreGood = FALSE ;
}
}
if (fAllUnitAreGood==TRUE)
{ /*** If all units are good units ***/
/*** 1. Write M to the Mathematical/Lookup table => Reset the bit ***/
/*** 2. wNoOfUnitsMatched++ ***/
MATCH_MarkUnitAsMathematical(flashPtr,wUnit);
*wNoOfUnitsMatched = *wNoOfUnitsMatched + 1 ;
}
else /* Some units are bad */
{
/*** 1. Write L to the Mathematical/Lookup table => Set the bit ***/
MATCH_MarkUnitAsLockup(flashPtr,wUnit);
if (dwOpAlgorithm==MTD_AM)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -