📄 matchalg.c
字号:
{
/*** 2. If the unit belongs to a new plane array Erase the waiting to be matched table */
if ((wUnit/dwLogicalUnitsInPlaneArray)!=MATCH_VARS->waitingToBeMatched.wPlaneArrayIndex)
MATCH_waitingToBeMatched_EraseAllItems (flashPtr) ;
/*** 3. Keep the good units in "waiting to be matched" table ***/
for (i=0;i<flashPtr->noOfPlanes;i++)
{
if(dwPhyUnitArray[i] != PHYSICAL_BLOCK_IS_BAD)
{
/* Mask the PhysicalUnits to be the UnitOffset in the flash */
dwPhyUnitArray[i] %= (MTD_VARS->dwLogicalUnitsInBank<<MTD_VARS->bNoOfPlanesBits) ;
MATCH_waitingToBeMatched_Add (flashPtr,(PhyUnitType)(dwPhyUnitArray[i])) ;
MATCH_VARS->waitingToBeMatched.wPlaneArrayIndex = (FLWord)(wUnit/dwLogicalUnitsInPlaneArray) ;
}
}
/*** 4. Check if you have in the waiting to be matched table a
set of N physical Units that resides in planes 0..N ***/
fFoundMatchInTable = TRUE ;
for (i=0;i<flashPtr->noOfPlanes;i++)
{
/* Search if there is a unit in plane i */
fUnitInPlaneWasFound=FALSE ;
for (j=0;j<MATCH_VARS->waitingToBeMatched.noOfUnits;j++)
{
if ((MATCH_VARS->waitingToBeMatched.physicalUnit[j]%flashPtr->noOfPlanes)==i)
{
fUnitInPlaneWasFound = TRUE ;
wPhyUnitReadFromTable[i] = MATCH_VARS->waitingToBeMatched.physicalUnit[j] ;
break;
}
}
if (fUnitInPlaneWasFound==FALSE)
{
fFoundMatchInTable=FALSE ;
break;
}
}
if (fFoundMatchInTable==TRUE)
{
/* Mask the PhyUnits to be the Offset of the physicalUnit from the start
of the flash chip (in order to save memory for the LookUpTable) */
for (i=0;i<flashPtr->noOfPlanes;i++)
wPhyUnitReadFromTable[i] = (PhyUnitType)(wPhyUnitReadFromTable[i]) ;
/* Write to the Lookup Table that logical unit U is corellated
with the N physical units we have found */
if (AddToLookUpTable==TRUE)
MATCH_updateLOOKUP_Table (flashPtr,wUnit,wPhyUnitReadFromTable) ;
/* Removed the matched items from the Waiting to be matched table */
MATCH_waitingToBeMatched_Remove (flashPtr,wPhyUnitReadFromTable) ;
*wNoOfUnitsMatched = *wNoOfUnitsMatched + 1 ;
}
} /* End if - advanced matching algorithm was requested */
} /* End if - not all units are good */
if (wNoOfUnits==*wNoOfUnitsMatched)
{
/* The requested number of units was found */
*wLastUnitPtr=wUnit ;
return flOK;
}
} /* End - loop over units until enough good units found */
return flOK;
}
#endif /* MTD_READ_BBT */
/*********** The API routines between Logical & Physical MTD ************
************************************************************************/
/************************************************************************
* Name : MATCH_unitLogicalToPhysical
* This routine finds the matching between the logical unit to its
* physical units
* Parameters:
* wLogicalUnit :The Logical unit that we need to find its matching
* wPhysicalUnitArray: Array of the physical units offset from
* the floor start
* Returns :
* wPhysicalunit:The set of physical units that are matched to the Logical unit
* flOK on success.
* flGeneralFailure on failure
************************************************************************/
static FLStatus MATCH_unitLogicalToPhysical (FLFlash *flashPtr,
LogicUnitType wLogicalUnit,
PhyUnitType *wPhysicalUnitArray)
{
FLByte bPlane ;
#ifdef MTD_READ_BBT
if ((MATCH_VARS->fTablesForLogicalMapWereCreated==TRUE) &&
(MATCH_IsLookUpUnit(flashPtr,wLogicalUnit) ) )
{ /*** Since one of the partitions is AM we need to do the following ***/
/*** Search for the bit in the Mathematical/LookupTable ***/
/*** If this bit is M => Finds this using a simple mathematical rule ***/
/*** If this bit is L => Search the Matching in the LookUp table ***/
if (MATCH_searchLOOKUP_Table (flashPtr,wLogicalUnit,wPhysicalUnitArray)==FALSE)
{ /* The logical unit was not found in the LookUp table */
DBG_PRINT_WRN(FLZONE_MTD,"MATCH_unitLogicalToPhysical:The Logical unit was not found in the \r\n") ;
DBG_PRINT_WRN(FLZONE_MTD," :Lookup table => You asked for Logical Unit \r\n") ;
DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT(" :%u , which is bad => Error \r\n"),wLogicalUnit)) ;
return flUnitIsBad ;
}
return flOK ;
}
else /* Finds this using a simple mathematical rule */
#endif /* MTD_READ_BBT */
{
/*** If no partition is mapped as AM => The tables are not created ***/
/*** => Find the physical units using a simple mathematical rule ***/
for (bPlane=0;bPlane<flashPtr->noOfPlanes;bPlane++)
wPhysicalUnitArray[bPlane] = (FLWord)(((wLogicalUnit<<MTD_VARS->bNoOfPlanesBits) + bPlane) % (flashPtr->noOfPlanes*MTD_VARS->dwLogicalUnitsInBank)) ;
}
return flOK ;
}
#ifdef MTD_READ_BBT
/************************************************************************
* Name : MATCH_createLogicalMapping
* 1 - Find if the Logical mapping is necessary ?
* The Logical mapping is not needed:
* - When all the partitions are SM
* - When you have only one plane
* 2 - If it is the first time => Allocate tables
* 1.Allocate the Mathematical/Lookup Table
* 2.Allocate the LookUp table (if needed)
* 3 - Find the Logical unit for media headers according to the
* noOfSkippedUnits field.
* 4 - Find the Start Unit and the Stop Unit of each of the m
* media partitions.
*
* Parameters:
* flashPtr: The flash struct.
* The following arguments are passed using the flashPtr->args.XXX
* noOfPartitions : Number of partition to create
* partitionsFlags : An array indicating whether the partitions
* should use an Advanced matching MTD_AM or
* Simple mathematical matching MTD_SM
* noOfUnitsArray : An array indicating the required number of
* good blocks for each of the partitions.
*
* Returns :
* noOfFirstUnitsArray : An array returning the first unit of each
* of the newly created partitions
* unusedBlocks : Returns the number of good blocks not
* allocated to a partition. (can be negative)
* partitionLogicalSize : An array returning the logical size of each
* of the newly created partition including BB
* MATCH_VARS->TablesForLogicalMapWereCreated : TRUE a lookup was neccesary
* FALSE all matching is mathematical
* flOK on success, any other value on failure.
************************************************************************/
FLStatus MATCH_createLogicalMapping (FLFlash *flashPtr)
{
FLWord wMatchedNoOfUnits,wGoodLogicalUnitsFound;
MTDArgumentPacket *argsPackPtr ;
LogicUnitType wFirstUnit,wLastUnit ;
FLBoolean fFlag,fAllUnitAreGood,fMATCH_isGoodBlock ;
FLDword dwPhyUnitArray[MAX_NUMBER_OF_PLANES];
FLStatus status;
FLWord i,j ;
#ifndef FL_MALLOC
FLByte socketNo = (FLByte)flSocketNoOf (flashPtr->socket);
#endif
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: createLogicalMapping Entered.\r\n");
argsPackPtr = &flashPtr->args ;
checkStatus (MTD_VARS->asicSetInNormalMode (flashPtr)) ;
/* Clear internal matching data structures */
MATCH_waitingToBeMatched_EraseAllItems (flashPtr) ;
MATCH_EraseAllItemsLOOKUP_Table (flashPtr) ;
/*** Step 1 - Find if the Logical mapping is necessary ? ***/
/*** The Logical mapping is not needed: ***/
/*** - When all the partitions are SM ***/
/*** - When you have only one plane ***/
/*** In case that you exit => MATCH_VARS->TablesForLogicalMapWereCreated=FALSE ***/
/*** Dummy call to this function => so that it will fill the BBT buffer cache */
status = MTD_VARS->isGoodBlock (flashPtr,0,ALWAYS_READ_FROM_FLASH,&fMATCH_isGoodBlock) ;
if(status != flOK)
{
DBG_PRINT_ERR(FLZONE_MTD,"ERROR in createLogicalMapping: Failed reading BBT.\r\n");
return status;
}
/* Check that all partitions are not SM */
fFlag=TRUE ; /* The fFlag is set and will be reset if one of the partitions is AM */
for (i=0;i<argsPackPtr->noOfPartitions;i++)
{
if (argsPackPtr->partitionsFlags[i]==MTD_AM)
fFlag=FALSE ;
}
/*** 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 ***/
/*** The media header is stored in the First logical unit.The size of ***/
/*** the media header size is determined by the NoOfSkippedUnits ***/
checkStatus(MATCH_InitFirstAvailLogicalUnitTable (flashPtr)) ;
/*** If all of the partitions are SM or if there are no planes, then ***/
/*** there is no need for the lockup table or AM ***/
if ((fFlag==TRUE) || (flashPtr->noOfPlanes==1))
{
/*** Find from the table the first available logical unit in floor 0 ***/
wLastUnit = MATCH_VARS->FirstAvailUnitTable[0]; ;
for (i=0;i<argsPackPtr->noOfPartitions;i++)
{
/* Insert first unit to the noOfUnitsArray */
argsPackPtr->noOfFirstUnitsArray[i] = wLastUnit ;
wGoodLogicalUnitsFound = 0 ;
while (wGoodLogicalUnitsFound<argsPackPtr->noOfUnitsArray[i])
{
if (wLastUnit>=MTD_VARS->dwLogicalUnitsInPlatform)
{
argsPackPtr->unusedBlocks = (FLSDword)wGoodLogicalUnitsFound - (FLSDword)argsPackPtr->noOfUnitsArray[i] ;
for (j=i+1;j<argsPackPtr->noOfPartitions;j++)
argsPackPtr->unusedBlocks -= (FLSDword)argsPackPtr->noOfUnitsArray[j] ;
return flOK ;
}
/*** Check if this unit is not one of the unavailable units ***/
if (MATCH_IsLogicalUnitAvailable (flashPtr,wLastUnit))
{
/* Available unit =>Find the Physical unit using a simple mathematical rule */
fAllUnitAreGood = TRUE ;
for (j=0;j<flashPtr->noOfPlanes;j++)
{
dwPhyUnitArray[j]=(wLastUnit<<MTD_VARS->bNoOfPlanesBits)+j ;
/* Check if one of these physical units is bad block */
checkStatus(MTD_VARS->isGoodBlock (flashPtr,dwPhyUnitArray[j],USE_BBT_CACHE,&fMATCH_isGoodBlock));
if (fMATCH_isGoodBlock==FALSE)
fAllUnitAreGood = FALSE ;
}
if (fAllUnitAreGood==TRUE)
wGoodLogicalUnitsFound++ ;
}
wLastUnit++ ;
} /* End loop over a partition finding the good units */
argsPackPtr->partitionLogicalSize[i] = wLastUnit-argsPackPtr->noOfFirstUnitsArray[i] ;
/* Now wLastUnit holds the first logical unit of the next partition */
/* Make sure the next partition does not start on the unavailable blocks */
if(((wLastUnit % MTD_VARS->dwLogicalUnitsInFloor) == 0) &&
(wLastUnit < MTD_VARS->dwLogicalUnitsInPlatform ) )
wLastUnit = MATCH_VARS->FirstAvailUnitTable[wLastUnit /
MTD_VARS->dwLogicalUnitsInFloor];
} /* End loop over the required partitions */
/* Now Calculate the Unused good logical Blocks (using SM) */
argsPackPtr->unusedBlocks = 0 ;
for (;wLastUnit<MTD_VARS->dwLogicalUnitsInPlatform ; wLastUnit++)
{
/*** Check if this unit is not one of the unavailable units ***/
if (MATCH_IsLogicalUnitAvailable(flashPtr,wLastUnit))
{
/* Find the Physical unit using a simple mathematical rule */
fAllUnitAreGood = TRUE ;
for (j=0;j<flashPtr->noOfPlanes;j++)
{
dwPhyUnitArray[j]=(wLastUnit<<MTD_VARS->bNoOfPlanesBits)+j ;
/* Check if one of these physical units is bad block */
checkStatus(MTD_VARS->isGoodBlock (flashPtr,dwPhyUnitArray[j],USE_BBT_CACHE,&fMATCH_isGoodBlock));
if (fMATCH_isGoodBlock==FALSE)
fAllUnitAreGood = FALSE ;
}
if (fAllUnitAreGood==TRUE)
argsPackPtr->unusedBlocks++ ;
}
}
return flOK ;
} /* End if - use simple matching - no lookup */
/*** Step 2 - If it is the first time => Allocate tables ***/
/*** 1.Allocate the Mathematical/Lookup Table ***/
/*** 2.Allocate the LookUp table (if needed) ***/
if (MATCH_VARS->fTablesForLogicalMapWereCreated==FALSE)
{
MATCH_VARS->mathLookup.dwTableSize = MTD_VARS->dwLogicalUnitsInPlatform >> 3 ; /* Table size in bytes */
/* dwNumOfEntries holds the number of entries the LookUp table has */
MATCH_VARS->lookUpTable.dwNumOfEntries = flashPtr->maxBadPercentage*MTD_VARS->dwLogicalUnitsInPlatform/100 ;
#ifdef FL_MALLOC
/*** Allocate the MATH_LOOKUP table ***/
MATCH_VARS->mathLookup.bTable = (FLByte *) FL_MALLOC (MTD_VARS->dwLogicalUnitsInPlatform >> 3) ;
/*** Allocate the Logical LookUpTable ***/
MATCH_VARS->lookUpTable.logicalUnit = (LogicUnitType *) FL_MALLOC ((FLDword)flashPtr->maxBadPercentage*
MTD_VARS->dwLogicalUnitsInPlatform/100 * (FLDword)sizeof(LogicUnitType)*
(FLDword)((1<<MTD_VARS->bNoOfPlanesBits)-1)) ;
MATCH_VARS->lookUpTable.physicalUnit = (PhyUnitType *) FL_MALLOC ((FLDword)flashPtr->maxBadPercentage*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -