⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlayer.c

📁 一个nand flash管理的算法(匈牙利算法)
💻 C
📖 第 1 页 / 共 3 页
字号:


	ml_mapinfo->mappagecou_hi=0;
	ml_mapinfo->mappagecou_lo=0;

	for (cou=0; cou<MAX_NUM_OF_DIF_MAP; cou++) {
		ST_MAPBLOCK *map=&ml_mapblocks[cou];
		t_ba lba=map->start_frag;

		lba*=MAX_FRAGSIZE;

		ml_createmap(map,0);

		if (ml_get_log2phy(lba)==BLK_NA) return 1;
		if (ml_save_map()) return 1;
	}
	
	ml_state=ML_CLOSE;

	return 0;
}

/****************************************************************************
 *
 * ml_findlog
 *
 * Searching for a log block (check if logical block is logged)
 * it sets ml_curlog to a log block or set it to NULL
 *
 * INPUTS
 *
 * lba - logical block address
 *
 * RETURNS 
 *
 * 1 - if found
 * 0 - not found
 *
 ***************************************************************************/

static t_bit ml_findlog(t_ba lba) {
ST_LOG *log=ml_log;
long a;
	for (a=0; a<MAX_LOG_BLOCK; a++,log++) {
		if (log->lba==lba) {
			ml_curlog=log;
			return 1;
		}
	}
	ml_curlog=0;
	return 0;
}

/****************************************************************************
 *
 * ml_dostatic
 *
 * does static wear leveling, its read logical block, updates static wear
 * info, and if static request is coming, then copy the block 
 *
 ***************************************************************************/

static void ml_dostatic() {   //把空闲block中wear最大的block与逻辑block中wear最小的block交换
unsigned long wear;           //实现擦写均衡
t_ba pba; 

	ml_lbastatic++;
	if (ml_lbastatic>=ml_data_blk_count) ml_lbastatic=0;

	pba=ml_get_log2phy(ml_lbastatic);
	if (pba==BLK_NA) return; //nothing to do

	if (!ll_read(pba,0,ml_buffer)) {; //get original
	 	wear=GET_SPARE_AREA(ml_buffer)->wear;
		if (wear<WEAR_NA) wear_updatestaticinfo(ml_lbastatic,wear);
		else wear_updatestaticinfo(ml_lbastatic,0);
	}
	else wear_updatestaticinfo(ml_lbastatic,0);

	if (wear_check_static()) {
		t_po po;
		t_ba d_pba,lba;
		t_ba s_pba;
		unsigned char index=gl_wear_allocstruct.free_index;

		if (index==INDEX_NA) return;
		d_pba=gl_freetable[index];

		if (wll_erase(101,d_pba)) {

			d_pba=bb_setasbb(d_pba);			  //get a reserved block
			if (d_pba==BLK_NA) {		 		  //if reserved not available
				gl_freetable[index] |= FT_BAD;    //signal it as BAD
			}
			else {
				wear_updatedynamicinfo(index,0); //set new reserved block wear
				gl_freetable[index] = d_pba;	 //put f_pba back into FLTable as FREE
			}

			return;
		}

#ifdef _WINDOWS
		cnt_increase(CNT_TSTATIC);
#endif

		lba=gl_wear_allocstruct.static_logblock;
		s_pba=ml_get_log2phy(lba);
		if (s_pba==BLK_NA) return; //nothing to do

		for (po=0; po<MAX_PAGE_PER_BLOCK; po++) {
			int ret=ll_read(s_pba,po,ml_buffer);
			if (!po) {
				ST_SPARE *sptr=GET_SPARE_AREA(ml_buffer);
				sptr->wear=gl_wear_allocstruct.free_wear;
				sptr->block_type=BLK_TYPE_DAT;
				sptr->bad_tag=0xff;
			}
			else if (ret) continue;

			if (wll_write(10,d_pba,po,ml_buffer)) return; //we can stop static swap
		
		}

		ml_set_log2phy(lba,d_pba);
		wear_updatestaticinfo(lba,gl_wear_allocstruct.free_wear);

		gl_freetable[index]=s_pba;
		wear_updatedynamicinfo(index,gl_wear_allocstruct.static_wear);

		ml_save_map();
	}
}


/****************************************************************************
 *
 * ml_alloclog
 *
 * alloc log block and initiate it
 *
 * INPUTS
 *
 * log - pointer where to alloc to
 * lba - which logical block is connected to log block
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/

static t_bit ml_alloclog(ST_LOG *log,t_ba lba) {
unsigned char index=ml_alloc();
t_ba pba;

	if (index==INDEX_NA) return 1;

	pba=gl_freetable[index];;

	log->index=index;
	log->lastppo=0;
	log->lba=lba;
	log->pba=pba;
	log->wear=gl_wear_allocstruct.free_wear;
	log->switchable=1;

	gl_freetable[index]=(t_ba)(pba | FT_LOG);
	wear_updatedynamicinfo(index,log->wear); //locked now
	ml_logblocknum++;

	memset(log->ppo,INDEX_NA,sizeof(log->ppo));

	ml_save_map_need=1;

	return 0;
}

/****************************************************************************
 *
 * ml_open
 *
 * Opening the chanel for read or write from a specified sector
 *
 * INPUTS
 *
 * sector - start of sector for read or write
 * secnum - number of sector will be read or written
 * mode - ML_READ open for read, ML_WRITE open for write
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/
//全局变量赋值
t_bit ml_open(unsigned long sector, unsigned long secnum, unsigned char mode) {

   if (ml_state==ML_INIT) return 1;

	ml_state=ML_CLOSE;
    ml_seccou=secnum;

	ml_lba=(t_ba)(sector/MAX_PAGE_PER_BLOCK);
	ml_lpo=(t_po)(sector%MAX_PAGE_PER_BLOCK);

	if (ml_lba>=ml_data_blk_count) return 1;
	if (ml_lpo>=MAX_PAGE_PER_BLOCK) return 1;

	if (mode==ML_READ) ml_state=ML_PENDING_READ;
	else if (mode==ML_WRITE) ml_state=ML_PENDING_WRITE;
	else return 1;

	return 0;
}


/****************************************************************************
 *
 * ml_domerge
 *
 * does log block and logical block merge
 *
 * INPUTS
 *
 * log - log block pointer (it contains logical block number also)
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/

static t_bit ml_domerge(ST_LOG *log) {
unsigned long wear=WEAR_NA;
unsigned char po,lpo,index;
t_ba pba;
t_ba orig_pba;

	ml_dostatic();

	ml_save_map_need=1;
//非常精彩
	if (log->lastppo==MAX_PAGE_PER_BLOCK && log->switchable) { // check if switchable

		orig_pba=ml_get_log2phy(log->lba);
		if (orig_pba==BLK_NA) return 1; // fatal

		ml_set_log2phy(log->lba,log->pba);		//put log block to original
		wear_updatestaticinfo(log->lba,log->wear);

		if (!ll_read(orig_pba,0,ml_buffer)) {//get original
		 	wear=GET_SPARE_AREA(ml_buffer)->wear;
		}
		else wear=0;

		gl_freetable[log->index]=orig_pba; //release original
		if (wear<WEAR_NA) wear_updatedynamicinfo(log->index,wear);
		else wear_updatedynamicinfo(log->index,0);

		ml_curlog->lba=BLK_NA;

		ml_logblocknum--;

		return 0;
	}
	
again: //缺陷:可能一直在写同一个坏的块,从而陷入死循环
	index=ml_alloc();
	if (index==INDEX_NA) return 1;
	pba=gl_freetable[index];
	orig_pba=ml_get_log2phy(log->lba);
	if (orig_pba==BLK_NA) return 1; //fatal

	for (po=0; po<MAX_PAGE_PER_BLOCK; po++) {
		lpo=log->ppo[po];						
		if (lpo==INDEX_NA) {
//			if (po && 
				ll_read(orig_pba,po,ml_buffer);
			//) continue; //get original
			if (!po) wear=GET_SPARE_AREA(ml_buffer)->wear;
		}
		else {
//			if (po && 
				ll_read(log->pba,lpo,ml_buffer);
				//) continue;	 //get logged
		}

		if (!po) {
			ST_SPARE *sptr=GET_SPARE_AREA(ml_buffer);
			sptr->wear=gl_wear_allocstruct.free_wear;
			sptr->block_type=BLK_TYPE_DAT;
			sptr->bad_tag=0xff; 
		}

		if (wll_write(20,pba,po,ml_buffer)) goto again;
//		if(po == 20) goto again;  //测试代码
	}

	if (wear==WEAR_NA) {
		if (!ll_read(orig_pba,0,ml_buffer)) {
			wear=GET_SPARE_AREA(ml_buffer)->wear;//get original
		}
		else {
			wear=0;
		}
	}

	gl_freetable[index]=orig_pba; //release original
	if (wear<WEAR_NA) wear_updatedynamicinfo(index,wear);
	else wear_updatedynamicinfo(index,0);

	gl_freetable[log->index]&=~FT_LOG;	 //release old log block
	wear_updatedynamicinfo(log->index,WEAR_NA);

	ml_set_log2phy(log->lba,pba);		//put new block to original
	wear_updatestaticinfo(log->lba,gl_wear_allocstruct.free_wear);

	ml_curlog->lba=BLK_NA;

	ml_logblocknum--;

	return 0;
}


/****************************************************************************
 *
 * ml_releaselog
 *
 * releasing a log block for a new logical block
 *
 * INPUTS
 *
 * lba - logical block address for new log block
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/

static t_bit ml_releaselog(t_ba lba) {
	if (ml_logblocknum < MAX_LOG_BLOCK) {
		if (ml_findlog(BLK_NA)) { //find a free
			return ml_alloclog(ml_curlog,lba);
		}
	}

	{
		ST_LOG *log=&ml_log[ml_logmerge++];
		if (ml_logmerge>=MAX_LOG_BLOCK) ml_logmerge=0;

		ml_curlog=log;
		if (ml_domerge(log)) return 1;
		return ml_alloclog(log,lba);
	}
}

/****************************************************************************
 *
 * ml_write
 *
 * Writing sector data
 *
 * INPUTS
 *
 * data - data pointer for an array which length is sector size
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/

t_bit ml_write(unsigned char *datap) {

#ifdef _WINDOWS
	cnt_increase(CNT_TWRITES);
#endif

	if (ml_state==ML_PENDING_WRITE) {
		if (!ml_findlog(ml_lba))	{
			if (ml_releaselog(ml_lba)) return 1;
		}
		ml_state=ML_WRITE;
	}

	if (ml_state==ML_WRITE) {

      	if (!ml_seccou--) {
         	ml_state=ML_ABORT;
         	return 1;
      	}

		if (ml_lpo>=MAX_PAGE_PER_BLOCK) {
			ml_lba++;
			if (ml_lba>=ml_data_blk_count) {
				ml_state=ML_CLOSE;
				return 1;
			}
			
			if (!ml_findlog(ml_lba)) {
				if (ml_releaselog(ml_lba)) return 1;
			}
			ml_lpo=0;
		}

		if (ml_curlog->lastppo>=MAX_PAGE_PER_BLOCK) {
			if (ml_domerge(ml_curlog)) return 1;
			if (ml_alloclog(ml_curlog,ml_lba)) return 1;		//allocate a new log block
		}


		memcpy (ml_buffer,datap,MAX_DATA_SIZE);

		{
			ST_SPARE *sptr=GET_SPARE_AREA(ml_buffer);
			if (!ml_curlog->lastppo) {
				sptr->wear=ml_curlog->wear;
				sptr->block_type=BLK_TYPE_DAT;
				sptr->bad_tag=0xff;
			}
			sptr->u.log.lba=ml_lba;
			sptr->u.log.lpo=ml_lpo;
		}

		if (ml_lpo!=ml_curlog->lastppo) ml_curlog->switchable=0; //not switchable from this point

		ml_curlog->ppo[ml_lpo++]=ml_curlog->lastppo;

		wll_write(40,ml_curlog->pba,ml_curlog->lastppo++,ml_buffer); //致命缺陷:写错误处理不足

		if (ml_save_map_need) ml_save_map();

		return 0;
	}

	return 1;
}

/****************************************************************************
 *
 * ml_read
 *
 * read sector data
 *
 * INPUTS
 *
 * data - where to read a given sector
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/

t_bit ml_read(unsigned char *datap) {
	if (ml_state==ML_PENDING_READ) {
		ml_pba=ml_get_log2phy(ml_lba);
		if (ml_pba==BLK_NA) return 1;

		ml_findlog(ml_lba);
		ml_state=ML_READ;
	}

	if (ml_state==ML_READ) {
		int ret;

      	if (!ml_seccou--) {
        	ml_state=ML_ABORT;
         	return 1;
      	}

		if (ml_lpo>=MAX_PAGE_PER_BLOCK) {
			ml_lba++;
			if (ml_lba>=ml_data_blk_count) {
				ml_state=ML_CLOSE;
				return 1;
			}
			ml_pba=ml_get_log2phy(ml_lba);
			if (ml_pba==BLK_NA) return 1;

			ml_findlog(ml_lba);
			ml_lpo=0;
		}

		if (ml_curlog) {                                                //对于log,页内也存在映射
			t_po po=ml_curlog->ppo[ml_lpo];
			if (po==INDEX_NA) ret=ll_read(ml_pba,ml_lpo,ml_buffer);
			else ret=ll_read(ml_curlog->pba,po,ml_buffer);
		}
		else {
			ret=ll_read(ml_pba,ml_lpo,ml_buffer);
		}

		memcpy (datap,ml_buffer,MAX_DATA_SIZE);

		ml_lpo++;

		if (ret==LL_OK) return 0;
		else if (ret==LL_ERASED) return 0; //erased
		return 1;
	}

	return 1;
}

/****************************************************************************
 *
 * ml_close
 *
 * closing sector reading or writing
 *
 * RETURNS
 *
 * 0 - if success
 * other if any error
 *
 ***************************************************************************/

t_bit ml_close() {
t_bit ret=0;

	if (ml_state==ML_INIT) return 1;

	if (ml_seccou) ret=1;
	if (ml_state==ML_ABORT) ret=1;

	ml_state=ML_CLOSE;
	return ret;
}


/****************************************************************************
 *
 * End of mlayer.c
 *
 ***************************************************************************/

#endif	//_MLAYER_C_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -