亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
国产精品久久久久永久免费观看| 欧美一区二区三区白人| 国产精品一区二区久久不卡| 日韩av一区二| 看片的网站亚洲| 久久国产精品99久久久久久老狼| 日本欧美一区二区三区| 激情五月激情综合网| 久久成人麻豆午夜电影| 国产毛片精品视频| 成人午夜免费电影| 91亚洲国产成人精品一区二三 | 精品免费视频一区二区| 精品少妇一区二区三区日产乱码| 精品国一区二区三区| 久久久久久一级片| 亚洲国产激情av| 亚洲免费色视频| 日韩精品一二三| 国产高清亚洲一区| 99re6这里只有精品视频在线观看| 99精品久久只有精品| 欧美午夜精品久久久| 欧美一区二区三区四区在线观看| 26uuu精品一区二区| 国产精品美女久久久久av爽李琼| 亚洲一区二区在线播放相泽| 麻豆精品久久久| av电影在线观看完整版一区二区| 91久久人澡人人添人人爽欧美| 欧美巨大另类极品videosbest | 丰满亚洲少妇av| 欧美在线看片a免费观看| 欧美一级生活片| 中文字幕一区二区三区四区| 午夜精品一区在线观看| 国产盗摄女厕一区二区三区| 欧美系列在线观看| 久久九九久精品国产免费直播| 一区二区三区在线观看网站| 精品影视av免费| 欧美色综合影院| 亚洲国产精品二十页| 蜜桃在线一区二区三区| 91香蕉视频mp4| 精品欧美一区二区三区精品久久| 亚洲综合图片区| 成人av综合在线| 精品国产网站在线观看| 亚洲国产精品视频| 欧美老人xxxx18| 亚洲天堂av一区| 国内外成人在线| 日韩欧美一级在线播放| 亚洲国产欧美在线| 91麻豆自制传媒国产之光| 精品国产麻豆免费人成网站| 水野朝阳av一区二区三区| 色哟哟欧美精品| 国产精品久久久久国产精品日日| 精品综合免费视频观看| 欧美男人的天堂一二区| 亚洲线精品一区二区三区八戒| 成人深夜在线观看| 日本一区二区三区四区在线视频 | 中文字幕国产一区| 国产精品一区一区三区| 亚洲精品一区二区三区影院| 蜜臀av国产精品久久久久| 欧美疯狂性受xxxxx喷水图片| 亚洲一区在线观看免费观看电影高清| 国产成人丝袜美腿| 国产人成亚洲第一网站在线播放| 精品一区二区三区在线播放| 日韩女优毛片在线| 奇米一区二区三区| 日韩欧美不卡一区| 国产一区二区91| 久久精品欧美日韩精品| 东方欧美亚洲色图在线| 亚洲国产高清在线| 99久久精品国产一区二区三区 | 欧美精品一区二| 蜜桃视频免费观看一区| 欧美不卡视频一区| 国产精品一区二区黑丝| 欧美国产精品v| 色综合色综合色综合| 亚洲午夜精品网| 欧美一级高清大全免费观看| 极品销魂美女一区二区三区| 久久久国产午夜精品| av爱爱亚洲一区| 午夜精品久久久久久久久久久 | 欧美精品在线一区二区三区| 欧美a一区二区| 久久亚洲精品小早川怜子| 成人97人人超碰人人99| 一区二区三国产精华液| 欧美一区二区在线播放| 国产福利不卡视频| 亚洲美女淫视频| 日韩一级高清毛片| 成人激情视频网站| 午夜精品久久久| 国产女同性恋一区二区| 欧美日韩亚洲国产综合| 激情综合色综合久久| 亚洲色欲色欲www| 欧美sm美女调教| 色婷婷av久久久久久久| 激情五月激情综合网| 夜夜揉揉日日人人青青一国产精品| 欧美一区二区精品| 91香蕉国产在线观看软件| 久久激情综合网| 夜色激情一区二区| 精品久久人人做人人爽| 色网站国产精品| 国产不卡在线视频| 日本aⅴ精品一区二区三区 | 黑人精品欧美一区二区蜜桃 | 亚洲欧美欧美一区二区三区| 欧美一三区三区四区免费在线看| 成人午夜激情在线| 日韩激情中文字幕| 亚洲男人天堂一区| 中文字幕乱码久久午夜不卡| 日韩亚洲欧美成人一区| 欧美自拍偷拍一区| 不卡av免费在线观看| 国产一区二区女| 免费一级片91| 亚洲风情在线资源站| 亚洲精品乱码久久久久久久久 | 91久久国产综合久久| 国产精品18久久久久久久久| 亚洲香肠在线观看| 亚洲精品国产精品乱码不99| 国产视频一区不卡| 精品999在线播放| 欧美一级午夜免费电影| 4hu四虎永久在线影院成人| 欧亚一区二区三区| 色八戒一区二区三区| 91免费看`日韩一区二区| 高清av一区二区| 国产精品一区二区不卡| 国产精品一区一区| 高清不卡在线观看av| 波波电影院一区二区三区| 成人精品在线视频观看| 99在线精品免费| 97精品久久久午夜一区二区三区| 国产成人av在线影院| 成人av资源在线观看| 不卡免费追剧大全电视剧网站| 成人黄色国产精品网站大全在线免费观看| 久久福利资源站| 国产电影精品久久禁18| 成人av在线资源网站| www.久久久久久久久| 91麻豆蜜桃一区二区三区| 色94色欧美sute亚洲线路一ni| 在线精品视频一区二区| 色菇凉天天综合网| 欧美夫妻性生活| 久久久久国产免费免费| 国产精品动漫网站| 亚洲午夜成aⅴ人片| 免费高清在线视频一区·| 久久99热狠狠色一区二区| 国产99久久久国产精品免费看| 成人免费三级在线| 欧美在线观看禁18| 日韩三级伦理片妻子的秘密按摩| 久久综合色鬼综合色| 中文字幕一区免费在线观看| 亚洲r级在线视频| 国产精品自产自拍| 日本韩国一区二区| 精品国产91洋老外米糕| 亚洲视频一区二区免费在线观看| 亚洲一区二区三区在线| 精品制服美女久久| 91麻豆精东视频| 亚洲精品一区二区三区精华液 | 色综合天天狠狠| 日韩网站在线看片你懂的| 国产嫩草影院久久久久| 亚洲成av人片| 高清在线成人网| 欧美一区二区视频免费观看| 日本一区二区电影| 日韩影院精彩在线| 91麻豆免费观看| 国产日韩欧美精品综合| 日韩电影免费在线看| 成人激情免费视频| 久久欧美一区二区|