/*从芯片构造nstl表,应该已经初始化,否则用NstlInitNandIc
普通前向没有链的,都标记为头
普通后向没有链的,都标记为尾
正常的块,前向、后向表中对应,空闲块只需要前向关系
ffp平时0xFF,正常可用块,ffp=0,正常有数据块指向正确位置
逻辑块指向链头
之后前向表为头位置的物理块转逻辑翻译到逻辑转物理
前向块头指向同一个逻辑的,格式化掉短的(因此要先构造前后链表才好处理)*/
static int NstlConstruct(void)
{
word nBlock = ZERO;
word nLogBlock = ZERO;
byte nPage = ZERO;
boolean bBad = BFALSE;
NstlOob oob;
int ret = ZERO;
word* pPhy2LogTbl = PNULL; /*临时p2l表,用后释放*/
word nChain1Len = ZERO;
word nChain2Len = ZERO;
pPhy2LogTbl = (word*)malloc(alp_nandinfo.blocks_for_ic * sizeof(word));
if (!pPhy2LogTbl)
{
#ifdef DEBUG_NSTL
KPrintHex("nstlcons memget fail: ", ret, "/r/n");
#endif
return ret;
}
/*先全部重新设置*/
MemSet((byte*)pPhy2LogTbl, alp_nandinfo.blocks_for_ic * sizeof(word), 0xFF);
NstlTblsInit();
/*物理到逻辑翻译==========================================================*/
#if 0
/*头0块不检查*/
for (nBlock = HEAD_POINT_BLOCK_START;
HEAD_POINT_BLOCK_END >= nBlock;
nBlock++)
{/*保障块-----------------------------------------------------------------*/
if (ZERO < s__nNstlHeadBlock)
{/*保障块已经检查OK*/
continue;
}
if (NandIsBadBlock(nBlock))
{/*不ok的只要标记是否bad,后面另构造*/
pPhy2LogTbl[nBlock] = BLOCK_BAD;
s__pNextTbl[nBlock] = BLOCK_BAD;
s__pPrevTbl[nBlock] = BLOCK_BAD;
s__pFfpTbl[nBlock] = 0xFF;
continue;
}
/*ok的标记,后面另构造*/
continue;
}
#endif
/*其它nstl管理块*/
for (nBlock =(word) (s_endBlockinx + 1);
nBlock < alp_nandinfo.blocks_for_ic;
nBlock++)
{
if (GN_OK != _GetBlockFfp(nBlock, &nPage, &bBad, &oob))
{/*包含检查坏块功能*/
if (bBad)
{/*坏块*/
JoinBadInit(nBlock);
pPhy2LogTbl[nBlock] = BLOCK_BAD;
continue;
}
/*抹除后自由*/
NandErase(nBlock << alp_nandinfo.block_shift);
JoinFreeInit(nBlock);
pPhy2LogTbl[nBlock] = BLOCK_FREE;
continue;
}
if (ZERO == nPage)
{/*自由*/
JoinFreeInit(nBlock);
pPhy2LogTbl[nBlock] = BLOCK_FREE;
continue;
}
/*在用*/
pPhy2LogTbl[nBlock] = oob.nLBN;
JoinUsedInit(nBlock,
oob.nPBN,
oob.nLBN,
nPage);
}
/*逻辑块到物理============================================================*/
for (nBlock =(word)(s_endBlockinx + 1);
nBlock < alp_nandinfo.blocks_for_ic;
nBlock++)
{/*构造在用表的链,自由链已经构造好*/
if (BLOCK_HEAD != s__pPrevTbl[nBlock])
{/*不是头块,一定是正常的前向或空闲的前向,或坏块等*/
continue;
}
if (s__nFreeBlockHead == nBlock)
{/*空闲表的头,因为只有空闲表的头s__pPrevTbl[nBlock]才是BLOCK_HEAD,才能做到这,空闲链的其他块在上一个if就被阻止了 */
continue;
}
/*普通头块*/
nLogBlock = pPhy2LogTbl[nBlock];
if (LBN_NOT_VALID == nLogBlock)
{/*不一致*/
//每一个物理头块和在用块(链中块)oob都要含有合法的逻辑块号,而空闲块则没有逻辑块号
return GN_ERR;
}
if (LBN_NOT_VALID == s__pLog2PhyTbl[nLogBlock])
{/*第一次设置,正常*/
s__pLog2PhyTbl[nLogBlock] = nBlock;
continue;
}
/*已经设置一次不正常*/
nChain1Len = GetChainLength(s__pLog2PhyTbl[nLogBlock]);
nChain2Len = GetChainLength(nBlock);
if (nChain1Len >= nChain2Len)
{
FormatChainConstr(nBlock);
}
else
{
FormatChainConstr(s__pLog2PhyTbl[nLogBlock]);
s__pLog2PhyTbl[nLogBlock] = nBlock;
}
}
MemPut((byte*)pPhy2LogTbl);
#ifdef DEBUG_NSTL
kprint("tables ok/r/n");
#endif
return GN_OK;
}