亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? nftlcore.c

?? 根據fs2410移植過后的mtd驅動源碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* Linux driver for NAND Flash Translation Layer      *//* (c) 1999 Machine Vision Holdings, Inc.             *//* Author: David Woodhouse <dwmw2@infradead.org>      *//* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ *//*  The contents of this file are distributed under the GNU General  Public License version 2. The author places no additional  restrictions of any kind on it. */#define PRERELEASE#include <linux/config.h>#include <linux/kernel.h>#include <linux/module.h>#include <asm/errno.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/miscdevice.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/slab.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/hdreg.h>#include <linux/kmod.h>#include <linux/mtd/mtd.h>#include <linux/mtd/nand.h>#include <linux/mtd/nftl.h>#include <linux/mtd/blktrans.h>/* maximum number of loops while examining next block, to have a   chance to detect consistency problems (they should never happen   because of the checks done in the mounting */#define MAX_LOOPS 10000static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd){	struct NFTLrecord *nftl;	unsigned long temp;	if (mtd->type != MTD_NANDFLASH)		return;	/* OK, this is moderately ugly.  But probably safe.  Alternatives? */	if (memcmp(mtd->name, "DiskOnChip", 10))		return;	if (!mtd->block_isbad) {		printk(KERN_ERR"NFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n""Please use the new diskonchip driver under the NAND subsystem.\n");		return;	}	DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);	if (!nftl) {		printk(KERN_WARNING "NFTL: out of memory for data structures\n");		return;	}	memset(nftl, 0, sizeof(*nftl));	nftl->mbd.mtd = mtd;	nftl->mbd.devnum = -1;	nftl->mbd.blksize = 512;	nftl->mbd.tr = tr;	memcpy(&nftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo));	nftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY;        if (NFTL_mount(nftl) < 0) {		printk(KERN_WARNING "NFTL: could not mount device\n");		kfree(nftl);		return;        }	/* OK, it's a new one. Set up all the data structures. */	/* Calculate geometry */	nftl->cylinders = 1024;	nftl->heads = 16;	temp = nftl->cylinders * nftl->heads;	nftl->sectors = nftl->mbd.size / temp;	if (nftl->mbd.size % temp) {		nftl->sectors++;		temp = nftl->cylinders * nftl->sectors;		nftl->heads = nftl->mbd.size / temp;		if (nftl->mbd.size % temp) {			nftl->heads++;			temp = nftl->heads * nftl->sectors;			nftl->cylinders = nftl->mbd.size / temp;		}	}	if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {		/*		  Oh no we don't have		   mbd.size == heads * cylinders * sectors		*/		printk(KERN_WARNING "NFTL: cannot calculate a geometry to "		       "match size of 0x%lx.\n", nftl->mbd.size);		printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "			"(== 0x%lx sects)\n",			nftl->cylinders, nftl->heads , nftl->sectors,			(long)nftl->cylinders * (long)nftl->heads *			(long)nftl->sectors );	}	if (add_mtd_blktrans_dev(&nftl->mbd)) {		kfree(nftl->ReplUnitTable);		kfree(nftl->EUNtable);		kfree(nftl);		return;	}#ifdef PSYCHO_DEBUG	printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');#endif}static void nftl_remove_dev(struct mtd_blktrans_dev *dev){	struct NFTLrecord *nftl = (void *)dev;	DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);	del_mtd_blktrans_dev(dev);	kfree(nftl->ReplUnitTable);	kfree(nftl->EUNtable);	kfree(nftl);}#ifdef CONFIG_NFTL_RW/* Actual NFTL access routines *//* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used *	when the give Virtual Unit Chain */static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ){	/* For a given Virtual Unit Chain: find or create a free block and	   add it to the chain */	/* We're passed the number of the last EUN in the chain, to save us from	   having to look it up again */	u16 pot = nftl->LastFreeEUN;	int silly = nftl->nb_blocks;	/* Normally, we force a fold to happen before we run out of free blocks completely */	if (!desperate && nftl->numfreeEUNs < 2) {		DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n");		return 0xffff;	}	/* Scan for a free block */	do {		if (nftl->ReplUnitTable[pot] == BLOCK_FREE) {			nftl->LastFreeEUN = pot;			nftl->numfreeEUNs--;			return pot;		}		/* This will probably point to the MediaHdr unit itself,		   right at the beginning of the partition. But that unit		   (and the backup unit too) should have the UCI set		   up so that it's not selected for overwriting */		if (++pot > nftl->lastEUN)			pot = le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN);		if (!silly--) {			printk("Argh! No free blocks found! LastFreeEUN = %d, "			       "FirstEUN = %d\n", nftl->LastFreeEUN,			       le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));			return 0xffff;		}	} while (pot != nftl->LastFreeEUN);	return 0xffff;}static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock ){	u16 BlockMap[MAX_SECTORS_PER_UNIT];	unsigned char BlockLastState[MAX_SECTORS_PER_UNIT];	unsigned char BlockFreeFound[MAX_SECTORS_PER_UNIT];	unsigned int thisEUN;	int block;	int silly;	unsigned int targetEUN;	struct nftl_oob oob;	int inplace = 1;        size_t retlen;	memset(BlockMap, 0xff, sizeof(BlockMap));	memset(BlockFreeFound, 0, sizeof(BlockFreeFound));	thisEUN = nftl->EUNtable[thisVUC];	if (thisEUN == BLOCK_NIL) {		printk(KERN_WARNING "Trying to fold non-existent "		       "Virtual Unit Chain %d!\n", thisVUC);		return BLOCK_NIL;	}	/* Scan to find the Erase Unit which holds the actual data for each	   512-byte block within the Chain.	*/        silly = MAX_LOOPS;	targetEUN = BLOCK_NIL;	while (thisEUN <= nftl->lastEUN ) {                unsigned int status, foldmark;		targetEUN = thisEUN;		for (block = 0; block < nftl->EraseSize / 512; block ++) {			MTD_READOOB(nftl->mbd.mtd,				    (thisEUN * nftl->EraseSize) + (block * 512),				    16 , &retlen, (char *)&oob);			if (block == 2) {                                foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;                                if (foldmark == FOLD_MARK_IN_PROGRESS) {                                        DEBUG(MTD_DEBUG_LEVEL1,                                              "Write Inhibited on EUN %d\n", thisEUN);					inplace = 0;				} else {					/* There's no other reason not to do inplace,					   except ones that come later. So we don't need					   to preserve inplace */					inplace = 1;				}			}                        status = oob.b.Status | oob.b.Status1;			BlockLastState[block] = status;			switch(status) {			case SECTOR_FREE:				BlockFreeFound[block] = 1;				break;			case SECTOR_USED:				if (!BlockFreeFound[block])					BlockMap[block] = thisEUN;				else					printk(KERN_WARNING					       "SECTOR_USED found after SECTOR_FREE "					       "in Virtual Unit Chain %d for block %d\n",					       thisVUC, block);				break;			case SECTOR_DELETED:				if (!BlockFreeFound[block])					BlockMap[block] = BLOCK_NIL;				else					printk(KERN_WARNING					       "SECTOR_DELETED found after SECTOR_FREE "					       "in Virtual Unit Chain %d for block %d\n",					       thisVUC, block);				break;			case SECTOR_IGNORE:				break;			default:				printk("Unknown status for block %d in EUN %d: %x\n",				       block, thisEUN, status);			}		}		if (!silly--) {			printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",			       thisVUC);			return BLOCK_NIL;		}		thisEUN = nftl->ReplUnitTable[thisEUN];	}	if (inplace) {		/* We're being asked to be a fold-in-place. Check		   that all blocks which actually have data associated		   with them (i.e. BlockMap[block] != BLOCK_NIL) are		   either already present or SECTOR_FREE in the target		   block. If not, we're going to have to fold out-of-place		   anyway.		*/		for (block = 0; block < nftl->EraseSize / 512 ; block++) {			if (BlockLastState[block] != SECTOR_FREE &&			    BlockMap[block] != BLOCK_NIL &&			    BlockMap[block] != targetEUN) {				DEBUG(MTD_DEBUG_LEVEL1, "Setting inplace to 0. VUC %d, "				      "block %d was %x lastEUN, "				      "and is in EUN %d (%s) %d\n",				      thisVUC, block, BlockLastState[block],				      BlockMap[block],				      BlockMap[block]== targetEUN ? "==" : "!=",				      targetEUN);				inplace = 0;				break;			}		}		if (pendingblock >= (thisVUC * (nftl->EraseSize / 512)) &&		    pendingblock < ((thisVUC + 1)* (nftl->EraseSize / 512)) &&		    BlockLastState[pendingblock - (thisVUC * (nftl->EraseSize / 512))] !=		    SECTOR_FREE) {			DEBUG(MTD_DEBUG_LEVEL1, "Pending write not free in EUN %d. "			      "Folding out of place.\n", targetEUN);			inplace = 0;		}	}	if (!inplace) {		DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "		      "Trying out-of-place\n", thisVUC);		/* We need to find a targetEUN to fold into. */		targetEUN = NFTL_findfreeblock(nftl, 1);		if (targetEUN == BLOCK_NIL) {			/* Ouch. Now we're screwed. We need to do a			   fold-in-place of another chain to make room			   for this one. We need a better way of selecting			   which chain to fold, because makefreeblock will			   only ask us to fold the same one again.			*/			printk(KERN_WARNING			       "NFTL_findfreeblock(desperate) returns 0xffff.\n");			return BLOCK_NIL;		}	} else {            /* We put a fold mark in the chain we are folding only if               we fold in place to help the mount check code. If we do               not fold in place, it is possible to find the valid               chain by selecting the longer one */            oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);            oob.u.c.unused = 0xffffffff;            MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,                         8, &retlen, (char *)&oob.u);        }	/* OK. We now know the location of every block in the Virtual Unit Chain,	   and the Erase Unit into which we are supposed to be copying.	   Go for it.	*/	DEBUG(MTD_DEBUG_LEVEL1,"Folding chain %d into unit %d\n", thisVUC, targetEUN);	for (block = 0; block < nftl->EraseSize / 512 ; block++) {		unsigned char movebuf[512];		int ret;		/* If it's in the target EUN already, or if it's pending write, do nothing */		if (BlockMap[block] == targetEUN ||		    (pendingblock == (thisVUC * (nftl->EraseSize / 512) + block))) {			continue;		}                /* copy only in non free block (free blocks can only                   happen in case of media errors or deleted blocks) */                if (BlockMap[block] == BLOCK_NIL)                        continue;                ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),				  512, &retlen, movebuf);                if (ret < 0) {                    ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])                                      + (block * 512), 512, &retlen,                                      movebuf);                    if (ret != -EIO)                        printk("Error went away on retry.\n");                }		memset(&oob, 0xff, sizeof(struct nftl_oob));		oob.b.Status = oob.b.Status1 = SECTOR_USED;                MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),                             512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo);	}        /* add the header so that it is now a valid chain */        oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum                = cpu_to_le16(thisVUC);        oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;        MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,                     8, &retlen, (char *)&oob.u);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
激情成人午夜视频| 日韩av电影天堂| 久久久噜噜噜久久人人看 | 2欧美一区二区三区在线观看视频| 美女看a上一区| 精品系列免费在线观看| 免费观看在线综合色| 理论片日本一区| 极品少妇xxxx偷拍精品少妇| 国产一区二三区| 高潮精品一区videoshd| av中文字幕一区| 在线精品视频免费观看| 欧美精品电影在线播放| 日韩女同互慰一区二区| 国产日本亚洲高清| 一区二区三区国产| 日本麻豆一区二区三区视频| 麻豆freexxxx性91精品| 成人激情av网| 欧美色倩网站大全免费| 精品久久久久久久久久久久包黑料| 久久综合色婷婷| 中文字幕亚洲区| 免费看日韩a级影片| 国产v综合v亚洲欧| 欧美日韩一区三区四区| 日韩精品在线一区二区| 中文字幕欧美一| 日本不卡中文字幕| 成人app网站| 欧美一区二区人人喊爽| 欧美激情在线观看视频免费| 亚洲电影第三页| 国产成人精品免费在线| 欧美日韩在线综合| 日本一区免费视频| 日韩电影免费在线| av成人动漫在线观看| 日韩一区二区三区视频| 亚洲卡通动漫在线| 免费观看日韩av| 在线亚洲人成电影网站色www| 日韩一级免费观看| 亚洲午夜羞羞片| 成人少妇影院yyyy| 欧美xingq一区二区| 夜夜爽夜夜爽精品视频| 国产久卡久卡久卡久卡视频精品| 91国产精品成人| 国产精品美女久久久久久久久久久 | 欧美性感一类影片在线播放| 久久一留热品黄| 美腿丝袜亚洲一区| 欧美日韩国产首页在线观看| 亚洲欧洲www| 国产成人小视频| 精品999久久久| 免费久久精品视频| 91麻豆精品国产91久久久使用方法| 亚洲天堂免费在线观看视频| 国内精品久久久久影院色| 欧美一级专区免费大片| 亚洲福利视频一区| 欧美亚洲动漫精品| 亚洲综合一区二区| 91麻豆自制传媒国产之光| 国产嫩草影院久久久久| 国产在线播精品第三| 欧美成人精品福利| 激情深爱一区二区| 国产亚洲va综合人人澡精品| 国产精品自产自拍| 久久久电影一区二区三区| 美女精品自拍一二三四| 日韩三级视频在线观看| 七七婷婷婷婷精品国产| 国产精品主播直播| 九色综合国产一区二区三区| 欧美一级片在线| 麻豆国产一区二区| 五月激情丁香一区二区三区| 91福利国产精品| 日本电影亚洲天堂一区| 国产精品白丝jk白祙喷水网站| 亚洲国产精品麻豆| 中文字幕一区二区三区乱码在线| 日韩欧美亚洲国产精品字幕久久久 | 99久久精品国产精品久久| 老司机午夜精品| 亚洲成人自拍一区| 亚洲免费观看高清完整| 国产精品全国免费观看高清| 精品国产乱码久久久久久牛牛| 欧美人牲a欧美精品| 在线亚洲免费视频| 色94色欧美sute亚洲线路一ni| 国产精品一二三区| 激情偷乱视频一区二区三区| 视频一区二区三区在线| 亚洲最新在线观看| 国产精品日韩精品欧美在线| 久久色在线观看| 久久久久久麻豆| 久久久亚洲精品石原莉奈| 日韩丝袜情趣美女图片| 日韩午夜av电影| 日韩一级片在线播放| 91精品国产综合久久久蜜臀粉嫩 | 蜜桃视频在线观看一区二区| 午夜精品久久久久久久久久久| 亚洲男人的天堂在线观看| 18欧美乱大交hd1984| 国产精品久久久久9999吃药| 中文字幕乱码亚洲精品一区| 国产精品国产自产拍在线| 国产精品久久久久久久久动漫| 欧美极品少妇xxxxⅹ高跟鞋 | 成人永久免费视频| 成人18视频在线播放| eeuss鲁一区二区三区| 91视频免费看| 欧美性一二三区| 欧美猛男gaygay网站| 欧美美女bb生活片| 精品动漫一区二区三区在线观看 | 7777精品伊人久久久大香线蕉完整版| 欧美在线三级电影| 欧美日韩免费在线视频| 91精品国产福利| 欧美精品一区二区三区蜜桃视频| 久久色成人在线| 亚洲欧美另类久久久精品| 艳妇臀荡乳欲伦亚洲一区| 日韩高清欧美激情| 国产综合久久久久影院| av一区二区久久| 在线成人小视频| 欧美激情一区二区| 亚洲一区av在线| 国产一区二区三区香蕉| 96av麻豆蜜桃一区二区| 538在线一区二区精品国产| 久久一区二区视频| 亚洲欧美激情一区二区| 久久99久国产精品黄毛片色诱| 国产精品18久久久久久久久| 91麻豆国产福利在线观看| 欧美日本国产一区| 国产精品欧美一区二区三区| 怡红院av一区二区三区| 蜜桃视频一区二区三区在线观看 | 中文字幕一区二区三区视频| 亚洲成人激情av| 国产传媒一区在线| 欧美日韩精品一区二区在线播放| 日韩免费高清av| 亚洲自拍与偷拍| 成人一二三区视频| 日韩欧美黄色影院| 亚洲综合在线五月| 国产精品伊人色| 91精品免费观看| 亚洲激情五月婷婷| 国产丶欧美丶日本不卡视频| 91麻豆精品国产91久久久久久久久 | 亚洲亚洲人成综合网络| 成人精品视频一区二区三区| 91精品在线观看入口| 亚洲女子a中天字幕| 国产综合久久久久影院| 欧美精选一区二区| 一区二区在线观看免费视频播放| 九九国产精品视频| 91精品国产一区二区三区| 樱花影视一区二区| av不卡免费电影| 中文字幕欧美三区| 国产在线精品国自产拍免费| 3751色影院一区二区三区| 一区二区欧美视频| 91丨九色porny丨蝌蚪| 国产精品免费视频网站| 韩国视频一区二区| 欧美一区二区播放| 日韩电影在线观看一区| 欧美日韩日日摸| 亚洲成人精品在线观看| 在线观看日韩电影| 亚洲一区二区综合| 色天使色偷偷av一区二区| 国产精品白丝在线| 成人美女在线视频| 国产女人aaa级久久久级 | 国产精品久久久爽爽爽麻豆色哟哟| 精品中文字幕一区二区| 精品国产一区二区三区四区四| 久久国产三级精品| 欧美本精品男人aⅴ天堂| 狠狠色伊人亚洲综合成人|