📄 m512_lgc.c
字号:
FLDword dwLogicalSector,dwLogicalSectorOffset ;
FLByte bPage,bMode_Shift = 0 ;
FLStatus status;
FLByte bNoOfReadSectors ;
FLDword dwNoOfSectors ;
FLDword dwOpFlags ;
argsPackPtr = &flashPtr->args ;
#ifndef FL_SKIP_ARGS_CHECK
if(argsPackPtr->startSector >= (flashPtr->mediaSize >> FL_SECTOR_SIZE_BITS))
{
DBG_PRINT_ERR(FLZONE_MTD,"ERROR - ACCESS outside the media space - logicalRead entered.\r\n");
return flGeneralFailure;
}
#endif /* FL_SKIP_ARGS_CHECK */
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: logicalRead entered.\r\n");
MTD_VARS->asicSetInNormalMode (flashPtr) ;
argsPackPtr->maxBitError = 0 ;
argsPackPtr->noOfSectorsPassed = 0 ;
argsPackPtr->freeSectorFound = 0 ;
dwOpFlags = argsPackPtr->opFlags ;
bMainBufferPtr = (FLByte FAR1 *)argsPackPtr->readMainBuf ;
bExtraBufferPtr = (FLByte FAR1 *)argsPackPtr->extraBuf ;
dwNoOfSectors = argsPackPtr->noOfSectors ;
dwLogicalSector = argsPackPtr->startSector ;
/*** We need to work in MTD_FAST_MODE mode when: ***/
/*** 1. The device is SLC type and no MTD_REL_MODE was given. ***/
/*** in that case we read as MTD_FAST_MODE mode ***/
/*** 2. The device is MLC but we were forced to work in MTD_FAST_MODE ***/
if ((MTD_VARS->bFlashType==M512_SLC_TYPE) && ((dwOpFlags & MTD_REL_MODE)==0))
dwOpFlags |= (MTD_REL_MODE|MTD_FAST_MODE) ;/*** Force OpFlag to work in MTD_FAST_MODE mode ***/
if ((dwOpFlags & MTD_REL_MODE) || (MTD_VARS->bFlashType==M512_SLC_TYPE))
bMode_Shift = 1 ;
while (dwNoOfSectors)
{
dwLogicalSectorOffset = dwLogicalSector ;
/*** Step 1: Find the floor that this sector belongs to,And set the floor ***/
bFloor = (FLByte)(dwLogicalSectorOffset/(MTD_VARS->dwSectorsInFloor>>bMode_Shift)) ;
/*** Step 2: Mask the LogicalSectorOffset to be the logical sector offset ***/
/*** from the currect floor ***/
dwLogicalSectorOffset = dwLogicalSectorOffset%(MTD_VARS->dwSectorsInFloor>>bMode_Shift) ;
/*** Step 3: Find the bank that this sector belongs to,And set the floor ***/
/*** Step 4: Mask the LogicalSectorOffset to be the logical sector offset ***/
/*** from the currect bank ***/
dwLogicalSectorOffset = dwLogicalSectorOffset % (MTD_VARS->dwSectorsInBank>>bMode_Shift) ;
/*** Step 5: Find the Logical unit that this Logical sector belongs to ***/
wLogicalUnit = (LogicUnitType)(dwLogicalSector / (MTD_VARS->dwSectorsInLogicalUnit>>bMode_Shift)) ;
/*** Step 6: Mask the LogicalSectorOffset to be the logical sector offset ***/
/*** from the currect LogicalUnit ***/
dwLogicalSectorOffset = dwLogicalSectorOffset % (MTD_VARS->dwSectorsInLogicalUnit>>bMode_Shift) ;
/*** Step 7: Find the page & plane that matched to the LogicalSectorNo ***/
bPage = (FLByte)(dwLogicalSectorOffset >> MTD_VARS->bNoOfPlanesBits) << bMode_Shift ;
/*** Step 8 : Find the Physiacl units that matched to this logical unit ***/
checkStatus (MTD_VARS->MATCH_unitLogicalToPhysical (flashPtr,wLogicalUnit,wPhysicalUnitArray)) ;
/*** Step 9 : Read the page to the buffer ***/
readArgs.sectorOffset = (FLWord)(dwLogicalSectorOffset % (1<<MTD_VARS->bNoOfPlanesBits)) ;
readArgs.phyUnits = wPhysicalUnitArray ;
readArgs.phyPage = bPage ;
readArgs.floor = bFloor ;
/*** Check whether to read of 2 sectors automatically ***/
if ( ((dwLogicalSectorOffset%2)==0) && (dwNoOfSectors>=2) && (dwOpFlags & MTD_DATA)
&& ((dwOpFlags & MTD_RAW_MODE)==0) && ((dwOpFlags & MTD_SW_EDC)==0) )
bNoOfReadSectors = 2 ;
else
bNoOfReadSectors = 1 ;
readArgs.noOfPhySectors = bNoOfReadSectors ;
readArgs.mainBuffer = bMainBufferPtr ;
readArgs.extraBuffer = bExtraBufferPtr ;
readArgs.opFlags = dwOpFlags ;
readArgs.offset = argsPackPtr->offset ;
readArgs.length = argsPackPtr->length ;
status = M512_read_Seq (flashPtr,&readArgs);
/*** If we Fail Try "second chance" to read ***/
/*** and if it doesnt succeed return the status error ***/
if ((status==flSequenceError) || (status==flDataError))
{
readArgs.noOfPhySectors = bNoOfReadSectors ;
readArgs.phyUnits = wPhysicalUnitArray ;
status = M512_read_Seq (flashPtr,&readArgs); /* If the error is Data/Sequence erro => Try to read again */
}
/*** Calculate the output parameters of the routine ***/
/*** 1.freeSectorFound field ***/
/*** 2.noOfSectorsPassed field ***/
/*** 3.maxBitError field ***/
if ( ((dwOpFlags & MTD_DATA)==0) && ((dwOpFlags & MTD_RAW_MODE)==0) )
argsPackPtr->freeSectorFound += readArgs.freeSectorsFound ;
argsPackPtr->noOfSectorsPassed += readArgs.noOfSectorsPassed ;
if (readArgs.maxBitErrors>argsPackPtr->maxBitError)
argsPackPtr->maxBitError = readArgs.maxBitErrors ;
#ifdef QA_ACCESORIES
QA_CountBitFlips (flashPtr,readArgs.maxBitErrors) ;
#endif
/*** After calculating the outputs the return the status ***/
if (status)
{
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: logicalRead exited.\r\n");
return status ;
}
/*** Advance the MainBuffer & ExtraBuffer pointers ***/
bMainBufferPtr = BYTE_ADD_FAR (bMainBufferPtr,(FLASH_SECTOR_DATA_SIZE * (FLWord)bNoOfReadSectors)) ;
if ((readArgs.extraBuffer) && (readArgs.opFlags & MTD_EXTRA))
{
bExtraBufferPtr = BYTE_ADD_FAR (bExtraBufferPtr,(bNoOfReadSectors*FLASH_EXTRA_BUFFER_SIZE)) ;
#ifndef NO_PHYSICAL_IO
if(readArgs.opFlags & MTD_SW_EDC)
bExtraBufferPtr = BYTE_ADD_FAR (bExtraBufferPtr,(bNoOfReadSectors*(FLASH_SECTOR_HM_SIZE+FLASH_SECTOR_BCH_SIZE))) ;
#endif /* NO_PHYSICAL_IO */
}
dwLogicalSector += bNoOfReadSectors;
dwNoOfSectors -= bNoOfReadSectors ;
}
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: logicalRead exited.\r\n");
return flOK ;
}
#ifndef FL_READ_ONLY
/**********************************************************************************
* logicalWrite
*
* MTD specific Flash write routine
*
* Parameters:
* flashPtr : Pointer identifying drive
*
* The routine uses the following inputs:
* flashPtr.arguments.noOfSectors : The number of sectors to read.
* flashPtr.arguments.startSector : First sector to start reading from
* flashPtr.arguments.writeMainBuf: Pointer to user buffer where the
* data of the logical sector's main
* area will be read into.
* flashPtr.arguments.extraBuf : Pointer to user buffer where the
* data of the sector info would read
* into.
* flashPtr.arguments.verifyWriteMode:An indicator of the read after
* write mode. FL_ON will force a
* read after write operation while
* FL_OFF will disable it.
* flashPtr.arguments.delayedStatus: A pointer to where the output of
* the operation will be returned,
* when adding the MTD_DO_NOT_WAIT
* flag.
* flashPtr.arguments.opFlags : Available flags are:
* MTD_DATA : Write to sector info area to mainBuf.
* MTD_EXTRA : Write to sector extra area to extraBuf.
* MTD_REL_MODE : Tells the controller the data is written
* in the reliable mode. .
* MTD_FAST_MODE : Tells the controller the data is to be
* written in the fast mode.If this
* flag isn't set and the MTD_REL_MODE
* mode is set, the MTD will use the
* reliable mode.
* MTD_DO_NOT_WAIT : Forces the MTD to return without polling
* the last sector write operation.
* MTD_SW_EDC : Allows access to the rest of the page's
* extra area.When this flag is set the
* extra area buffer is extended to 16
* bytes and will include the hamming,
* BCH and dummy byte.No EDC\ECC will be
* employed.
* MTD_NO_MATCHING : This mode tells the MTD not to match physical blocks into logical blocks. *
* Practically this mode exports the
* physical addressing.
* The routine sets the following outputs:
* flashPtr.arguments.maxBitsError :Returns maximum bit error found
* in read after write operation
* flashPtr.arguments.noOfSectorsPassed:The number of sectors that were
* successfully written.
*
* The routine return the following error codes:
* Returns:
* flOK : Success
* flWriteFault : The write operation failed to one of the
* required sectors.
* flHWProtection : A protection violation has occurred while
* attempting to write to one of the sectors..
* flTimedOut : The maximum delay time has expired, but the
* device is not ready yet.
* flSequenceError : The ASIC has detected Sequence Error
*
* ----------------------------------------------------------------------------
*| The MTD_ DATA & MTD_EXTRA opFlags combinatin is as follows: |
*|----------------------------------------------------------------------------|
*| opFlags | writeMainBuf | extraBuf | Implications |
*|----------------------------------------------------------------------------|
*| Only MTD_ DATA | VALID | N/A | Not supported |
*|----------------------------------------------------------------------------|
*| Only MTD_EXTRA | N/A | VALID | Limitation: |
*| | | | - Only one sector |
*| | | | can be written using this |
*| | | | opFlags combination. |
*| MTD_DATA|MTD_EXTRA | VALID | VALID | Supported |
*| | NULL | VALID | Supported with limitation |
*| | | | - Only one sector can be |
*| | | | written using this |
*| | | | opFlags combination. |
* ----------------------------------------------------------------------------
*********************************************************************************/
FLStatus M512_logicalWrite (FLFlash *flashPtr)
{
MTDArgumentPacket *argsPackPtr ;
LogicUnitType wLogicalUnit ;
FLByte bFloor ;
PhyUnitType wPhysicalUnitArray[M512_MAX_NUMBER_OF_PLANES] ;
const FLByte FAR1 *bMainBufferPtr ;
FLByte FAR1 *bExtraBufferPtr ;
M512_OperationArgsStruct writeArgs ;
FLDword dwLogicalSectorOffset,dwNoOfSectors,dwLogicalSectorNo ;
FLByte bPage,bNoOfWrittenSectors,bMode_Shift = 0 ;
FLStatus status ;
FLDword dwDoNotPollFlag ;
FLDword dwOpFlags ;
argsPackPtr = &flashPtr->args ;
#ifndef FL_SKIP_ARGS_CHECK
if(argsPackPtr->startSector >= (flashPtr->mediaSize >> FL_SECTOR_SIZE_BITS))
{
DBG_PRINT_ERR(FLZONE_MTD,"ERROR - ACCESS outside the media space - logicalWrite entered.\r\n");
return flGeneralFailure;
}
#endif /* FL_SKIP_ARGS_CHECK */
DBG_PRINT_FLOW(FLZONE_MTD,"Flow: logicalWrite entered.\r\n");
flashPtr->completeOperation (flashPtr) ;
MTD_VARS->asicSetInNormalMode (flashPtr) ;
argsPackPtr->maxBitError = 0 ;
argsPackPtr->noOfSectorsPassed = 0 ;
bMainBufferPtr = (FLByte FAR1 *)argsPackPtr->writeMainBuf ;
bExtraBufferPtr = (FLByte FAR1 *)argsPackPtr->extraBuf ;
dwLogicalSectorNo = argsPackPtr->startSector ;
dwNoOfSectors = argsPackPtr->noOfSectors ;
dwDoNotPollFlag = argsPackPtr->opFlags & MTD_DO_NOT_WAIT ;
dwOpFlags = argsPackPtr->opFlags & ~dwDoNotPollFlag ;
/*** We need to work in FAST mode when: ***/
/*** 1. The device is SLC type and no MTD_REL_MODE was given. ***/
/*** in that case we read as MTD_FAST_MODE mode ***/
/*** 2. The device is MLC type but we were forced to work in MTD_FAST_MODE ***/
if ((MTD_VARS->bFlashType==M512_SLC_TYPE) && ((dwOpFlags & MTD_REL_MODE)==0))
dwOpFlags |= (MTD_REL_MODE|MTD_FAST_MODE) ;/*** Force OpFlag to work in MTD_FAST_MODE mode ***/
if ((dwOpFlags & MTD_REL_MODE) || (MTD_VARS->bFlashType==M512_SLC_TYPE))
bMode_Shift = 1 ;
while (dwNoOfSectors)
{
dwLogicalSectorOffset = dwLogicalSectorNo ;
/*** Step 1: Find the floor that this sector belongs to,And set the floor ***/
bFloor = (FLByte)(dwLogicalSectorOffset/(MTD_VARS->dwSectorsInFloor>>bMode_Shift)) ;
/*** Step 2: Mask the LogicalSectorOffset to be the logical sector offset ***/
/*** from the currect floor ***/
dwLogicalSectorOffset = dwLogicalSectorOffset % (MTD_VARS->dwSectorsInFloor>>bMode_Shift) ;
/*** Step 3: Find the bank that this sector belongs to,And set the floor ***/
/*** Step 4: Mask the LogicalSectorOffset to be the logical sector offset ***/
/*** from the currect bank ***/
dwLogicalSectorOffset = dwLogicalSectorOffset % (MTD_VARS->dwSectorsInBank>>bMode_Shift) ;
/*** Step 5: Find the Logical unit that this Logical sector belongs to ***/
wLogicalUnit = (LogicUnitType)(dwLogicalSectorNo / (MTD_VARS->dwSectorsInLogicalUnit>>bMode_Shift)) ;
/*** Step 6: Mask the LogicalSectorOffset to be the logical sector offset ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -