📄 smt_fat.c
字号:
return(SMT_E_FAILURE);
}
else
{
iRetVal = smtGetDevInfo(bDevice);
if(iRetVal != SMT_E_SUCCESS)
{
return(SMT_E_FAILURE);
}
if(smt_pDevInf->bMaker != 0x00) // A maker code is checked.
{
if(smt_pDevInf->bMaker != bMaker)
{
smtErrInf.iSmtErr = SMT_E_DEVNOSP;
return(SMT_E_FAILURE);
}
}
}
//////////////////////////////////
/// BAD BLOCK CHECK (ALL-ZONE) ///
//////////////////////////////////
if(smtCntBadBlk() != SMT_E_SUCCESS) // Bad block in all the zones is checked.
{
return(SMT_E_FAILURE);
}
/////////////////////////////////
/// FORMAT CHECK & MAKE TABLE ///
/////////////////////////////////
iRetVal = smtPhyFmtChk(&ulCisBlk); // The check of the format and a block table
if(iRetVal == SMT_E_SUCCESS) // - are made.
{
iRetVal = smtInitInsInfo(ulCisBlk);
if(iRetVal == SMT_E_SUCCESS)
{
iRetVal = smtLogFmtChk();
if(iRetVal == SMT_E_SUCCESS)
{
fatFatInit(pstParams);
}
}
}
return(iRetVal);
}
/************************************************************************
* smtGetDevInfo
* Type : int
* Ret val : Error code
* SMT_SUCCESS ( 0) ... Successful
* SMT_FAILURE (-1) ... Failure
* Argument : unsigned char bDevice ... Device code
* Function : This function acquires information on device from
* device code.
************************************************************************/
int smtGetDevInfo(
unsigned char bDevice // Device code
)
{
int iType; // Device type index
int iModel; // Device model index
smt_pDevInf = NULL; // Device information of the media is
iType = 0; // - searched from acquired device code.
while((smt_pDevInf == NULL)&&(iType < SMT_TYP_MAX))
{
iModel = 0;
while(iModel < SMT_MDL_MAX)
{
if(smtDevInf[iType][iModel].bDevice == bDevice)
{
smt_pDevInf = &smtDevInf[iType][iModel];
return(SMT_E_SUCCESS);
}
iModel++;
}
iType++;
}
smtErrInf.iSmtErr = SMT_E_DEVNOSP;
return(SMT_E_FAILURE);
}
/************************************************************************
* smtCntBadBlk
* Type : int
* Ret val : Error code
* Argument : None
* Function : This function checks the number of bad blocks in all
* the zones.
************************************************************************/
int smtCntBadBlk(
void
)
{
unsigned long ulLogBlk; // Logic block address
unsigned long ulPage; // Page address
ulLogBlk = 0;
while(ulLogBlk < smt_pDevInf->pSizeInf->ulNumBlk)
{
ulPage = smtChgPgNum(ulLogBlk / SMT_ZON_MAX, ulLogBlk % SMT_ZON_MAX, 0x00);
if(pSmt_PageRead(SMT_C_DREAD_3, 0x00, ulPage, smtRead.stBuff.bProlix) == SMT_E_SUCCESS)
{
if(smtChkBadBlk(smtRead.stDatBuff.bBlkSts) != SMT_E_SUCCESS)
{
if(++smtBadBlkCnt > smt_pDevInf->pSizeInf->uwBadBlk)
{
smtErrInf.iSmtErr = SMT_E_BADBLCK;
return(SMT_E_FAILURE);
}
}
}
else
{
smtErrInf.iSmtErr = SMT_E_PAGREAD;
return(SMT_E_FAILURE);
}
ulLogBlk++;
}
return(SMT_E_SUCCESS);
}
/************************************************************************
* smtInitInsInfo
* Type : int
* Ret val : Error code
* Argument : unsigned long ulCisBlk ... CIS block address (Physics)
* Function : This function makes the block table of the zone 0.
************************************************************************/
int smtInitInsInfo(
unsigned long ulCisBlk
)
{
unsigned long ulPhyBlk; // Physics block address
unsigned long ulPhyBlkMax; // Max value of physics block address.
unsigned char bCheckBit; // Check bit information
bCheckBit = ulCisBlk + 1; // A logic block address and physics block
bCheckBit %= 8; // - address information table are made.
bCheckBit = SMT_M_MASK(bCheckBit);
smtClrBlkTbl(0);
smtClrBlkTbl(1);
if(smt_pDevInf->pSizeInf->ulNumBlk < SMT_ZON_MAX)
{
ulPhyBlkMax = smt_pDevInf->pSizeInf->ulNumBlk;
}
else
{
ulPhyBlkMax = SMT_ZON_MAX;
}
ulPhyBlk = ulCisBlk + 1;
while(ulPhyBlk < ulPhyBlkMax)
{
if(ulPhyBlk != ulCisBlk + 1)
{
bCheckBit <<= 1;
if(!bCheckBit)
{
bCheckBit = 0x01;
}
}
smtCrtBlkTbl(0, ulPhyBlk, bCheckBit);
ulPhyBlk++;
}
return(SMT_E_SUCCESS);
}
/************************************************************************
* smtClrBlkTbl
* Type : int
* Ret val : Error code
* Argument : unsigned long ulZone ... Zone address
* Function : This function clears a block table.
************************************************************************/
void smtClrBlkTbl(
unsigned long ulZone // Zone address
)
{
unsigned char bIndex; // Table index
if(!ulZone) // A block information table is initialized.
{
bIndex = 0;
}
else
{
bIndex = 1;
}
smtBlkTbl[bIndex].ulZoneNum = 0;
smtBlkTbl[bIndex].ulBlockNum = 0;
memset(smtBlkTbl[bIndex].bBlkCnvInf, 0xFF, SMT_BLK_ALLOC);
memset(smtBlkTbl[bIndex].bBlkPhyInf, 0x00, SMT_BLK_ENTRY);
memset(smtBlkTbl[bIndex].bBlkChkInf, 0x00, SMT_BLK_CHECK);
}
/************************************************************************
* smtCrtBlkTbl
* Type : int
* Ret val : Error code
* Argument : unsigned long ulZone ... Zone address
* unsigned long ulPhyBlk ... Physics block address
* unsigned char bCheckBit ... Check bit information
* Function : Create block table function
************************************************************************/
int smtCrtBlkTbl(
unsigned long ulZone, // Zone address
unsigned long ulPhyBlk, // Physics block address
unsigned char bCheckBit // Check bit information
)
{
unsigned long ulPage; // Page address
unsigned char bIndex; // Access Index
unsigned long ulLbaBlk; // Logic block address area data
unsigned long ulLogBlk; // Logic block address
unsigned long ulOldPhyBlk; // Old physics block address
////////////////////////
/// READ PROLIX DATA ///
//////////////////////// // The good reason of the block is validated
ulPage = smtChgPgNum(ulZone, ulPhyBlk, 0x00); // - from the part prolix of the head page.
if(pSmt_PageRead(SMT_C_DREAD_3, 0x00, ulPage, smtRead.stBuff.bProlix) != SMT_E_SUCCESS)
{
smtErrInf.iSmtErr = SMT_E_PAGREAD;
return(SMT_E_FAILURE);
}
//////////////////////////
/// UPDATE BLOCK TABLE ///
//////////////////////////
if(!ulZone)
{
bIndex = 0;
}
else
{
bIndex = 1;
}
smtBlkTbl[bIndex].ulZoneNum = ulZone;
smtBlkTbl[bIndex].ulBlockNum = 0;
if(smtChkBadBlk(smtRead.stDatBuff.bBlkSts) != SMT_E_SUCCESS)
{
return(SMT_E_SUCCESS);
}
if((smtRead.stDatBuff.bBlkAdr1[0] == 0xFF) // The block which isn't unusual is registered
&&(smtRead.stDatBuff.bBlkAdr1[1] == 0xFF)) // - in the block management table.
{
smtBlkTbl[bIndex].bBlkPhyInf[ulPhyBlk / 8] |= bCheckBit;
return(SMT_E_SUCCESS);
}
ulLbaBlk = (smtRead.stDatBuff.bBlkAdr1[0] << 8) // The block which parity error occurred in isn't
| smtRead.stDatBuff.bBlkAdr1[1]; // - used.
if(smtChkPrty(ulLbaBlk) != SMT_E_SUCCESS)
{
return(SMT_E_SUCCESS); // Parity error isn't returned here.
}
ulLogBlk = smtChgLogNum(smtRead.stDatBuff.bBlkAdr1[0], smtRead.stDatBuff.bBlkAdr1[1]);
if(smtBlkTbl[bIndex].bBlkChkInf[ulLogBlk / 8] & SMT_M_MASK(ulLogBlk % 8))
{
ulOldPhyBlk = smtChgPhyNum(ulLogBlk);
if(ulOldPhyBlk != 0x0FFF)
{
smtChkDupli(ulZone, ulOldPhyBlk, ulPhyBlk);
}
}
else
{
smtBlkTbl[bIndex].bBlkCnvInf[ulLogBlk] = SMT_M_BYTE(ulPhyBlk, SMT_BYTE0);
smtBlkTbl[bIndex].bBlkChkInf[ulLogBlk / 8] |= SMT_M_MASK(ulLogBlk % 8);
}
return(SMT_E_SUCCESS);
}
/************************************************************************
* smtChkDupli
* Type : int
* Ret val : Error code
* Argument : unsigned long ulZone ... Zone address
* unsigned long ulOldPhyBlk ... Old physics block address
* unsigned long ulNewPhyBlk ... New physics block address
* Function : This function checked the block which has the same
* logic block number.
************************************************************************/
int smtChkDupli(
unsigned long ulZone, // Zone address
unsigned long ulOldPhyBlk, // Old physics block address
unsigned long ulNewPhyBlk // New physics block address
)
{
int iRetVal; // Return value
int iLoop; // Loop counter
unsigned long ulPage; // Page address
unsigned char bStatus; // Overlap status
unsigned char bIndex; // Zone index
unsigned char bHiBlk; // The high byte of the address.
unsigned char bLoBlk; // The low byte of the address.
unsigned long ulLogBlk; // Logic block address
unsigned long ulPhyBlk; // Physics block address
iRetVal = SMT_E_SUCCESS; // Return value is initialized.
bStatus = SMT_FALSE; // New block data status is initialized.
if(!ulZone)
{
bIndex = 0;
}
else
{
bIndex = 1;
}
/////////////////////////
/// SECTOR DATA CHECK /// // The check of the duplicate data is done.
///////////////////////// // Sector data is read, and ECC is checked.
ulPage = smtChgPgNum(ulZone, ulNewPhyBlk, 0x00);
if(smtPageReadWrap(SMT_C_DREAD_1, 0x00, ulPage, smtRead.bBuff) == SMT_E_SUCCESS)
{
iLoop = 0;
while(iLoop < 2)
{
bHiBlk = smtRead.stDatBuff.bBlkAdr1[0];
bLoBlk = smtRead.stDatBuff.bBlkAdr1[1];
if(smtChkPrty((bHiBlk << 8) | bLoBlk) == SMT_E_SUCCESS)
{
ulLogBlk = smtChgLogNum(bHiBlk, bLoBlk);
smtBlkTbl[bIndex].bBlkCnvInf[ulLogBlk] = SMT_M_BYTE(ulNewPhyBlk, 0);
bStatus = SMT_TRUE;
break;
}
iLoop++;
}
}
//////////////////////////
/// UPDATE ENTRY TABLE ///
//////////////////////////
if(bStatus == SMT_FALSE) // The validity of sector data is checked,
{ // - and unusual sector is erased.
ulPhyBlk = ulNewPhyBlk; // When neither is unusual, old sector is erased.
}
else
{
ulPhyBlk = ulOldPhyBlk;
}
ulPage = smtChgPgNum(ulZone, ulPhyBlk, 0x00);
iRetVal = pSmt_BlockErase(ulPage);
iRetVal = pSmt_EraseChk();
if(iRetVal == SMT_E_SUCCESS)
{
smtBlkTbl[bIndex].bBlkPhyInf[ulPhyBlk / 8] |= SMT_M_MASK(ulPhyBlk % 8);
}
else
{
iRetVal = smtEntryBadBlk(ulZone, ulPhyBlk);
}
return(iRetVal);
}
/************************************************************************
* smtGetEccVal
* Type : unsigned long
* Ret val : ECC value
* Argument : unsigned char *pBuff ... Data buffer (512+16 Bytes)
* unsigned char bArea ... Area switch
* (Not SMT_AREA_2 = AREA-1 / SMT_AREA_2 = AREA-2)
* Function : This function takes out the ECC value of prolix part.
************************************************************************/
unsigned long smtGetEccVal(
unsigned char *pBuff, // Data buffer
unsigned char bArea // Area switch
)
{
unsigned long ulEccVal; // ECC value
union SMT_PROLIX_BUFF *pChkBuff; // Check buffer
pChkBuff = (union SMT_PROLIX_BUFF *)pBuff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -