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

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

?? nftlcore.c

?? nandflash k9g808u0a在pxa270的驅動,由于pxa270沒有nandflash接口
?? 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.2 2007/09/21 03:09:24 quy 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)) {		if (nftl->ReplUnitTable)			kfree(nftl->ReplUnitTable);		if (nftl->EUNtable)			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);	if (nftl->ReplUnitTable)		kfree(nftl->ReplUnitTable);	if (nftl->EUNtable)		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;        

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩西西人体444www| 色香蕉久久蜜桃| 国产精品自在欧美一区| 中文字幕一区视频| 久久先锋资源网| 久久精品欧美日韩精品| 亚洲欧美成aⅴ人在线观看| 亚洲天堂成人网| 同产精品九九九| 开心九九激情九九欧美日韩精美视频电影 | 亚洲欧美另类在线| 一二三四社区欧美黄| 免费一区二区视频| 成人综合激情网| 在线播放/欧美激情| 99九九99九九九视频精品| 国产成人自拍高清视频在线免费播放| 另类综合日韩欧美亚洲| 国产在线精品一区二区三区不卡| 亚洲欧美日韩中文播放| 精品第一国产综合精品aⅴ| 日韩理论片中文av| 99riav久久精品riav| 国产欧美日韩在线看| 国产一区久久久| 欧美xxx久久| 国产一区二区三区精品视频| 欧美午夜宅男影院| 亚洲精品国产无套在线观| 99久久精品免费看国产| 亚洲男女一区二区三区| 一本色道亚洲精品aⅴ| 亚洲欧美色一区| 欧美日韩视频专区在线播放| 亚瑟在线精品视频| 欧美二区三区91| 国产在线视频一区二区三区| 久久欧美一区二区| 成人小视频在线观看| 亚洲美女免费在线| 欧美猛男男办公室激情| 蜜乳av一区二区三区| 国产视频视频一区| 97精品久久久久中文字幕| 亚洲一二三四久久| 精品久久久久久无| 91一区在线观看| 奇米精品一区二区三区在线观看| 欧美tk—视频vk| 91视频在线观看| 国产一区二区三区四区五区入口 | 蜜臀av性久久久久蜜臀aⅴ流畅| 精品精品欲导航| 色婷婷狠狠综合| 麻豆精品在线视频| 亚洲美女在线一区| 精品少妇一区二区三区日产乱码 | 亚洲一区二区在线观看视频| 精品免费国产一区二区三区四区| 99re这里只有精品首页| 精一区二区三区| 亚洲韩国精品一区| 中文字幕一区二区三区四区| 亚洲精品一区二区三区99| 色综合久久久久综合99| 国产成人亚洲综合a∨猫咪| 婷婷一区二区三区| 亚洲综合小说图片| 中文字幕第一页久久| 欧美韩国日本一区| 国产精品国产自产拍高清av王其| 久久色成人在线| 日韩精品一区二区三区中文不卡| 欧美吞精做爰啪啪高潮| 一本色道久久加勒比精品| av午夜一区麻豆| 91丨九色porny丨蝌蚪| 成人高清免费在线播放| 国产不卡视频在线观看| 风间由美一区二区三区在线观看 | 国产一区二区日韩精品| 91蝌蚪国产九色| 在线免费观看日本欧美| 欧美伊人久久大香线蕉综合69| 色综合色狠狠综合色| 欧美日韩一级视频| 欧美精品123区| 久久久久久免费毛片精品| 国产欧美日产一区| 一区二区三区欧美久久| 亚洲a一区二区| 国产一区激情在线| 成人av电影在线网| 欧美乱妇20p| 国产精品乱码久久久久久| 国产精品丝袜久久久久久app| 一二三四区精品视频| 天天综合色天天| av中文一区二区三区| 欧洲一区二区av| 久久影音资源网| 亚洲在线视频一区| 国产乱人伦精品一区二区在线观看 | jvid福利写真一区二区三区| 91精品午夜视频| 亚洲国产精品人人做人人爽| 国产精品一区在线观看你懂的| 欧美中文字幕一区| 久久久国产午夜精品| 久久99精品久久久久久国产越南| 在线观看av一区二区| 亚洲欧洲成人自拍| 国产激情精品久久久第一区二区| 欧美日韩黄色一区二区| 亚洲人成网站色在线观看| 国产成人综合网| 国产女人18毛片水真多成人如厕 | 亚洲综合一二三区| 91成人国产精品| 亚洲最大色网站| 91电影在线观看| 一区二区三区四区在线| 99精品国产热久久91蜜凸| 久久精品亚洲麻豆av一区二区 | 欧美一区二区三区色| 日韩在线一区二区| 欧美大片在线观看一区二区| 久久国产福利国产秒拍| 久久亚洲精精品中文字幕早川悠里 | www.性欧美| 亚洲午夜精品网| 91精品国产综合久久精品| 日韩1区2区3区| 亚洲精品一区二区三区福利| 成人自拍视频在线| 亚洲靠逼com| 日韩欧美精品三级| 成人午夜短视频| 亚洲午夜av在线| 精品国产乱码久久| 国产成人精品免费看| 欧美成人video| 91视频免费看| 韩国av一区二区三区| 亚洲欧美区自拍先锋| 日韩欧美激情四射| 91美女视频网站| 国产成人免费av在线| 日韩va亚洲va欧美va久久| 中文字幕亚洲成人| 日韩精品专区在线| 欧美在线free| av中文一区二区三区| 国产一区二区三区免费观看| 亚洲一区二区三区自拍| 国产欧美一区二区精品仙草咪| 3d动漫精品啪啪一区二区竹菊| 成人av高清在线| 国产一区二区三区黄视频| 日韩黄色免费网站| 亚洲影视在线播放| 日韩一区有码在线| 中文字幕一区二区三区不卡| 精品久久久影院| 欧美精品一区二区在线观看| 在线成人午夜影院| 欧美日韩精品一区二区三区| 91亚洲永久精品| 色乱码一区二区三区88| 在线观看区一区二| 欧美日韩国产乱码电影| 欧美亚洲一区二区三区四区| 欧美在线影院一区二区| 欧美日韩国产精选| 日韩精品一区二区三区蜜臀| 日韩写真欧美这视频| 日韩三级精品电影久久久| 久久夜色精品国产噜噜av| 国产精品系列在线| 亚洲激情综合网| 麻豆精品一区二区av白丝在线| 麻豆专区一区二区三区四区五区| 久久99久久精品欧美| 成人黄色综合网站| 在线观看一区二区精品视频| 777a∨成人精品桃花网| 国产色综合久久| 亚洲成av人片| 成人网男人的天堂| 欧美日高清视频| 国产精品第四页| 免费视频最近日韩| 色视频成人在线观看免| 久久色.com| 亚洲高清免费观看高清完整版在线观看 | 亚洲午夜精品网| 国产精品一区二区免费不卡| 色综合久久中文综合久久牛| 精品日韩av一区二区| 五月天亚洲精品|