Example #1
0
/*!
*
* \par  Description:
*       This function copy valuable data from log block or dat block to free block, change free to data ,change
*       data and log to free.
*
* \param  [in]       LogNum,serial number within log block space
* \return      sucess or failed.
* \note         this function was called when log block is not suit for swap or move.
**/
__s32  _free2data_simple_merge(__u32 nlogical)
{
    __u8 InData;
    __u16 SuperPage;
    __u16 SrcPage,DstPage;
    __u32 SrcBlk,DstBlk;
    struct __SuperPhyBlkType_t DataBlk;
    struct __SuperPhyBlkType_t FreeBlk;
    struct __LogBlkType_t LogBlk;
    struct __PhysicOpPara_t SrcParam,DstParam;

    /*init block info*/
    BMM_GetDataBlk(nlogical,&DataBlk);
	BMM_GetLogBlk(nlogical,&LogBlk);
    if (NAND_OP_TRUE != BMM_GetFreeBlk(LOWEST_EC_TYPE, &FreeBlk))
        return NAND_OP_FALSE;


    /*copy data from data block or log block to free block*/
	if((SUPPORT_LOG_BLOCK_MANAGE)&&(LogBlk.LogBlkType == LSB_TYPE))
	{
		//DBUG_INF("[DBUG] nand lsb type simple merge block %x\n", nlogical);
		for (SuperPage = 0; SuperPage < PAGE_CNT_OF_LOGIC_BLK; SuperPage++)
	    {
	        /*set source address and destination address*/
	        DstPage = SuperPage;
	        DstBlk = FreeBlk.PhyBlkNum;
	        SrcPage = PMM_GetCurMapPage(SuperPage);
	        InData = (SrcPage == 0xffff)?1 : 0;
			if(InData)
			{
				SrcBlk = DataBlk.PhyBlkNum;
			}
			else
			{
				if(SrcPage&(0x1<<15))
					SrcBlk = LogBlk.PhyBlk1.PhyBlkNum;
				else
					SrcBlk = LogBlk.PhyBlk.PhyBlkNum;
			}
	        SrcPage = InData?SuperPage:(SrcPage&0x7fff);
			LML_CalculatePhyOpPar(&SrcParam, CUR_MAP_ZONE,SrcBlk, SrcPage);
			LML_CalculatePhyOpPar(&DstParam, CUR_MAP_ZONE,DstBlk, DstPage);

	        if (DstPage == 0)
	        {
	            __u8 SeqPlus;
	            //SeqPlus = InData?1:0;
	            SeqPlus = InData?2:1;
	            if(NAND_OP_FALSE == _copy_page0(SrcBlk, SrcPage, DstBlk,SeqPlus))
	            {
	                LOGICCTL_ERR("simple_merge : copy page 0 err\n");
	                return NAND_OP_FALSE;
	            }
	        }
	        else
	        {
	            if(NAND_OP_TRUE != PHY_PageCopyback(&SrcParam,&DstParam))
	            {
	                LOGICCTL_ERR("simple merge : copy back err\n");
	                return NAND_OP_FALSE;
	            }
	        }

	        if(NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE))
	        {
	            struct __SuperPhyBlkType_t SubBlk;
	            if(NAND_OP_TRUE != LML_BadBlkManage(&FreeBlk,CUR_MAP_ZONE,DstPage, &SubBlk))
	            {
	                LOGICCTL_ERR("simgple merge : bad block manage err after copy back\n");
	                return NAND_OP_FALSE;
	            }
	            FreeBlk = SubBlk;
	            SuperPage -= 1;
	        }
	    }

	    /*move free block to data block*/
	    BMM_SetDataBlk(nlogical, &FreeBlk);


		/*move erased data block to free block*/
	    if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, DataBlk.PhyBlkNum)){
	        if (NAND_OP_TRUE != LML_BadBlkManage(&DataBlk,CUR_MAP_ZONE,0,NULL)){
	            LOGICCTL_ERR("swap merge : bad block manage err erase data block\n");
	            return NAND_OP_FALSE;
	        }
	    }
	    /*move erased data block to free block*/
	    if (DataBlk.BlkEraseCnt < 0xffff)
	        DataBlk.BlkEraseCnt ++;
	    BMM_SetFreeBlk(&DataBlk);
		//DBUG_INF("[DBUG] logic %x simple merge: erase data block: %x\n", LogBlk.LogicBlkNum, DataBlk.PhyBlkNum);

	    /*move erased log block to free block*/
	    if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum)){
	        if (NAND_OP_TRUE != LML_BadBlkManage(&LogBlk.PhyBlk,CUR_MAP_ZONE,0,NULL)){
	            LOGICCTL_ERR("simple merge : bad block manage err after erase log block\n");
	            return NAND_OP_FALSE;
	        }
	    }
	    if (LogBlk.PhyBlk.BlkEraseCnt < 0xffff)
	        LogBlk.PhyBlk.BlkEraseCnt ++;
	    BMM_SetFreeBlk(&LogBlk.PhyBlk);
		//DBUG_INF("[DBUG] logic %x simple merge: erase log block 0: %x\n", LogBlk.LogicBlkNum, LogBlk.PhyBlk.PhyBlkNum);

		 /*move erased log block to free block*/

		if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, LogBlk.PhyBlk1.PhyBlkNum)){
	        if (NAND_OP_TRUE != LML_BadBlkManage(&LogBlk.PhyBlk1,CUR_MAP_ZONE,0,NULL)){
	            LOGICCTL_ERR("simple merge : bad block manage err after erase log block\n");
	            return NAND_OP_FALSE;
	        }
	    }
	    if (LogBlk.PhyBlk1.BlkEraseCnt < 0xffff)
	        LogBlk.PhyBlk1.BlkEraseCnt ++;
	    BMM_SetFreeBlk(&LogBlk.PhyBlk1);
		//DBUG_INF("[DBUG] logic %x simple merge: erase log block 1: %x\n", LogBlk.LogicBlkNum, LogBlk.PhyBlk1.PhyBlkNum);

	    MEMSET(&LogBlk, 0xff, sizeof(struct __LogBlkType_t));
		LogBlk.LogBlkType = 0;
		LogBlk.WriteBlkIndex = 0;
		LogBlk.ReadBlkIndex = 0;
	    BMM_SetLogBlk(nlogical, &LogBlk);

	    /*clear page map table*/
	    PMM_ClearCurMapTbl();
	}
	else
	{
		for (SuperPage = 0; SuperPage < PAGE_CNT_OF_LOGIC_BLK; SuperPage++)
	    {
	        /*set source address and destination address*/
	        DstPage = SuperPage;
	        DstBlk = FreeBlk.PhyBlkNum;
	        SrcPage = PMM_GetCurMapPage(SuperPage);
	        InData = (SrcPage == 0xffff)?1 : 0;
	        SrcBlk = InData?DataBlk.PhyBlkNum : LogBlk.PhyBlk.PhyBlkNum;
	        SrcPage = InData?SuperPage:SrcPage;
			LML_CalculatePhyOpPar(&SrcParam, CUR_MAP_ZONE,SrcBlk, SrcPage);
			LML_CalculatePhyOpPar(&DstParam, CUR_MAP_ZONE,DstBlk, DstPage);

	        if (DstPage == 0)
	        {
	            __u8 SeqPlus;
	            //SeqPlus = InData?1:0;
	            SeqPlus = InData?2:1;
	            if(NAND_OP_FALSE == _copy_page0(SrcBlk, SrcPage, DstBlk,SeqPlus))
	            {
	                LOGICCTL_ERR("simple_merge : copy page 0 err\n");
	                return NAND_OP_FALSE;
	            }
	        }
	        else
	        {
	            if(NAND_OP_TRUE != PHY_PageCopyback(&SrcParam,&DstParam))
	            {
	                LOGICCTL_ERR("simple merge : copy back err\n");
	                return NAND_OP_FALSE;
	            }
	        }

	        if(NAND_OP_TRUE != PHY_SynchBank(DstParam.BankNum, SYNC_BANK_MODE))
	        {
	            struct __SuperPhyBlkType_t SubBlk;
	            if(NAND_OP_TRUE != LML_BadBlkManage(&FreeBlk,CUR_MAP_ZONE,DstPage, &SubBlk))
	            {
	                LOGICCTL_ERR("simgple merge : bad block manage err after copy back\n");
	                return NAND_OP_FALSE;
	            }
	            FreeBlk = SubBlk;
	            SuperPage -= 1;
	        }
	    }

	    /*move free block to data block*/
	    BMM_SetDataBlk(nlogical, &FreeBlk);


		/*move erased data block to free block*/
	    if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, DataBlk.PhyBlkNum)){
	        if (NAND_OP_TRUE != LML_BadBlkManage(&DataBlk,CUR_MAP_ZONE,0,NULL)){
	            LOGICCTL_ERR("swap merge : bad block manage err erase data block\n");
	            return NAND_OP_FALSE;
	        }
	    }
	    /*move erased data block to free block*/
	    if (DataBlk.BlkEraseCnt < 0xffff)
	        DataBlk.BlkEraseCnt ++;
	    BMM_SetFreeBlk(&DataBlk);


	    /*move erased log block to free block*/
	    if ( NAND_OP_TRUE != LML_VirtualBlkErase(CUR_MAP_ZONE, LogBlk.PhyBlk.PhyBlkNum)){
	        if (NAND_OP_TRUE != LML_BadBlkManage(&LogBlk.PhyBlk,CUR_MAP_ZONE,0,NULL)){
	            LOGICCTL_ERR("move merge : bad block manage err after erase log block\n");
	            return NAND_OP_FALSE;
	        }
	    }
	    if (LogBlk.PhyBlk.BlkEraseCnt < 0xffff)
	        LogBlk.PhyBlk.BlkEraseCnt ++;
	    BMM_SetFreeBlk(&LogBlk.PhyBlk);
	    MEMSET(&LogBlk, 0xff, sizeof(struct __LogBlkType_t));
		LogBlk.LogBlkType = 0;
		LogBlk.WriteBlkIndex = 0;
		LogBlk.ReadBlkIndex = 0;
	    BMM_SetLogBlk(nlogical, &LogBlk);

	    /*clear page map table*/
	    PMM_ClearCurMapTbl();
	}


    return NAND_OP_TRUE;

}