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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? nftlcore.c

?? 根據(jù)fs2410移植過后的mtd驅(qū)動源碼
?? 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);

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久久不卡网国产精品一区| 国产成人自拍网| 精品一区二区日韩| 高清不卡一二三区| 欧美性生活大片视频| 日韩欧美三级在线| 亚洲丝袜另类动漫二区| 日韩综合在线视频| 国产91丝袜在线播放0| 色综合久久88色综合天天| 欧美狂野另类xxxxoooo| 2021国产精品久久精品| 亚洲精品欧美在线| 国内精品免费在线观看| 色综合天天综合给合国产| 日韩亚洲欧美高清| 亚洲色图一区二区三区| 久久精品国产精品亚洲红杏| 99re亚洲国产精品| 日韩一区二区三区视频| 亚洲婷婷在线视频| 国产综合成人久久大片91| 色综合久久久久综合| 久久网站热最新地址| 亚洲最新在线观看| 成人综合在线观看| 欧美一区二区三级| 樱花影视一区二区| 丁香天五香天堂综合| 91.xcao| 自拍偷拍亚洲综合| 国产精品一品二品| 日韩亚洲欧美在线观看| 一区二区三区产品免费精品久久75| 黄一区二区三区| 在线播放91灌醉迷j高跟美女 | 亚洲综合在线视频| 国产不卡免费视频| 日韩视频免费观看高清完整版| 亚洲视频在线一区| 成人性生交大片免费| 欧美一区二区三区免费在线看 | 欧美日韩午夜在线视频| 中文字幕精品一区| 国产在线精品一区二区三区不卡 | 日韩在线播放一区二区| 色婷婷一区二区| 国产精品理伦片| 国产激情精品久久久第一区二区| 欧美一区二区三区在线| 亚洲国产精品自拍| 一本大道久久a久久精二百 | 色综合咪咪久久| 国产精品日产欧美久久久久| 久久精品国产在热久久| 在线播放中文一区| 亚洲午夜在线视频| 色婷婷综合在线| 亚洲男人的天堂在线aⅴ视频| 寂寞少妇一区二区三区| 日韩视频在线永久播放| 日韩二区三区四区| 欧美理论片在线| 亚洲资源中文字幕| 欧美性生活一区| 亚洲一区二区三区四区的| 91国产福利在线| 亚洲在线一区二区三区| 在线视频欧美精品| 艳妇臀荡乳欲伦亚洲一区| 色激情天天射综合网| 一区二区在线电影| 欧美亚洲免费在线一区| 亚洲国产美女搞黄色| 欧美三级三级三级爽爽爽| 亚洲bt欧美bt精品| 欧美精品电影在线播放| 日本不卡视频在线观看| 日韩欧美一区电影| 国内久久精品视频| 亚洲国产精品二十页| 99re这里只有精品首页| 一区二区成人在线| 欧美日韩成人一区二区| 麻豆91在线播放| 久久精品亚洲国产奇米99| 成人黄色网址在线观看| 自拍偷在线精品自拍偷无码专区| 色婷婷综合五月| 香蕉久久一区二区不卡无毒影院| 91精品福利在线一区二区三区 | 精品久久久久一区| 国产91在线看| 亚洲激情一二三区| 欧美剧在线免费观看网站| 六月婷婷色综合| 国产三级精品视频| 91福利国产精品| 奇米四色…亚洲| 日本一区二区免费在线观看视频| 91网上在线视频| 日韩av电影天堂| 久久精品一级爱片| 在线视频观看一区| 久久国产综合精品| 综合分类小说区另类春色亚洲小说欧美| 欧美伊人久久大香线蕉综合69| 天堂在线一区二区| 欧美韩国日本一区| 欧美日本一区二区在线观看| 激情图片小说一区| 有坂深雪av一区二区精品| 日韩一级大片在线| aaa国产一区| 免费一区二区视频| 最新欧美精品一区二区三区| 制服丝袜成人动漫| 国产精品自在欧美一区| 亚洲一区国产视频| 久久久精品黄色| 欧美日韩大陆在线| 成人免费视频免费观看| 午夜视频在线观看一区| 国产人成亚洲第一网站在线播放| 欧美自拍偷拍午夜视频| 国产乱码字幕精品高清av | 欧美日韩在线三级| 国产精品12区| 午夜精品福利一区二区三区蜜桃| 国产视频视频一区| 欧美老女人在线| 91丝袜国产在线播放| 久久精品国产成人一区二区三区| 亚洲情趣在线观看| 亚洲精品一线二线三线无人区| 欧美亚洲国产一区在线观看网站| 国产美女在线精品| 视频一区国产视频| 亚洲精品五月天| 欧美激情一区二区三区全黄| 7777精品伊人久久久大香线蕉的 | 亚洲另类春色校园小说| 久久久久久久网| 欧美顶级少妇做爰| 91免费观看国产| 国产乱色国产精品免费视频| 天天综合色天天综合色h| 日韩一区在线看| 国产欧美一区二区三区在线老狼 | 国内成+人亚洲+欧美+综合在线| 一区二区欧美在线观看| 欧美国产激情一区二区三区蜜月| 日韩欧美亚洲国产精品字幕久久久| 欧美影院一区二区| 91麻豆国产福利精品| 成人在线综合网| 国产综合一区二区| 久久99国产精品麻豆| 日韩精品亚洲一区| 亚洲成av人片一区二区三区| 亚洲视频免费在线观看| 国产精品久久久久永久免费观看 | 成人aaaa免费全部观看| 国产精品一区二区久久不卡| 久久成人免费电影| 蜜臀久久99精品久久久画质超高清| 夜夜亚洲天天久久| 亚洲最新视频在线观看| 亚洲欧美日韩在线不卡| 日韩一区欧美小说| 国产精品久久久久久久久免费桃花| 久久精品人人做| 久久精品欧美一区二区三区不卡 | 丁香婷婷综合五月| 粉嫩高潮美女一区二区三区| 国产精品影视在线观看| 国产一区二区三区四| 国产传媒久久文化传媒| 国产精品一区二区无线| 国产一区二区美女| 国产不卡高清在线观看视频| 高清不卡在线观看| jvid福利写真一区二区三区| a级精品国产片在线观看| 99国产一区二区三精品乱码| 91亚洲国产成人精品一区二三| av在线不卡电影| 在线免费观看视频一区| 欧美伊人久久久久久久久影院| 欧美少妇性性性| 欧美一级久久久久久久大片| 日韩你懂的在线播放| 久久综合久久鬼色| 国产日韩亚洲欧美综合| 中文字幕一区二区三区四区不卡 | 欧美日韩国产大片| 日韩一区二区精品在线观看| 日韩欧美国产一区在线观看| 欧美精品一区二区三区在线 | 91亚洲国产成人精品一区二区三 |