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

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

?? cfi_cmdset_0020.c

?? 根據(jù)fs2410移植過后的mtd驅(qū)動源碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* * Common Flash Interface support: *   ST Advanced Architecture Command Set (ID 0x0020) * * (C) 2000 Red Hat. GPL'd * * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $ * * 10/10/2000	Nicolas Pitre <nico@cam.org> * 	- completely revamped method functions so they are aware and * 	  independent of the flash geometry (buswidth, interleave, etc.) * 	- scalability vs code size is completely set at compile-time * 	  (see include/linux/mtd/cfi.h for selection) *	- optimized write buffer method * 06/21/2002	Joern Engel <joern@wh.fh-wedel.de> and others *	- modified Intel Command Set 0x0001 to support ST Advanced Architecture *	  (command set 0x0020) *	- added a writev function * 07/13/2005	Joern Engel <joern@wh.fh-wedel.de> * 	- Plugged memory leak in cfi_staa_writev(). */#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/init.h>#include <asm/io.h>#include <asm/byteorder.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/mtd/map.h>#include <linux/mtd/cfi.h>#include <linux/mtd/mtd.h>#include <linux/mtd/compatmac.h>static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);static int cfi_staa_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,		unsigned long count, loff_t to, size_t *retlen);static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *);static void cfi_staa_sync (struct mtd_info *);static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len);static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);static int cfi_staa_suspend (struct mtd_info *);static void cfi_staa_resume (struct mtd_info *);static void cfi_staa_destroy(struct mtd_info *);struct mtd_info *cfi_cmdset_0020(struct map_info *, int);static struct mtd_info *cfi_staa_setup (struct map_info *);static struct mtd_chip_driver cfi_staa_chipdrv = {	.probe		= NULL, /* Not usable directly */	.destroy	= cfi_staa_destroy,	.name		= "cfi_cmdset_0020",	.module		= THIS_MODULE};/* #define DEBUG_LOCK_BITS *///#define DEBUG_CFI_FEATURES#ifdef DEBUG_CFI_FEATURESstatic void cfi_tell_features(struct cfi_pri_intelext *extp){        int i;        printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);	printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");	printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");	printk("     - Suspend Program:    %s\n", extp->FeatureSupport&4?"supported":"unsupported");	printk("     - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported");	printk("     - Queued Erase:       %s\n", extp->FeatureSupport&16?"supported":"unsupported");	printk("     - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported");	printk("     - Protection Bits:    %s\n", extp->FeatureSupport&64?"supported":"unsupported");	printk("     - Page-mode read:     %s\n", extp->FeatureSupport&128?"supported":"unsupported");	printk("     - Synchronous read:   %s\n", extp->FeatureSupport&256?"supported":"unsupported");	for (i=9; i<32; i++) {		if (extp->FeatureSupport & (1<<i))			printk("     - Unknown Bit %X:      supported\n", i);	}	printk("  Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);	printk("     - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");	for (i=1; i<8; i++) {		if (extp->SuspendCmdSupport & (1<<i))			printk("     - Unknown Bit %X:               supported\n", i);	}	printk("  Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);	printk("     - Lock Bit Active:      %s\n", extp->BlkStatusRegMask&1?"yes":"no");	printk("     - Valid Bit Active:     %s\n", extp->BlkStatusRegMask&2?"yes":"no");	for (i=2; i<16; i++) {		if (extp->BlkStatusRegMask & (1<<i))			printk("     - Unknown Bit %X Active: yes\n",i);	}	printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",	       extp->VccOptimal >> 8, extp->VccOptimal & 0xf);	if (extp->VppOptimal)		printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",		       extp->VppOptimal >> 8, extp->VppOptimal & 0xf);}#endif/* This routine is made available to other mtd code via * inter_module_register.  It must only be accessed through * inter_module_get which will bump the use count of this module.  The * addresses passed back in cfi are valid as long as the use count of * this module is non-zero, i.e. between inter_module_get and * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000. */struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary){	struct cfi_private *cfi = map->fldrv_priv;	int i;	if (cfi->cfi_mode) {		/*		 * It's a real CFI chip, not one for which the probe		 * routine faked a CFI structure. So we read the feature		 * table from it.		 */		__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;		struct cfi_pri_intelext *extp;		extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics");		if (!extp)			return NULL;		if (extp->MajorVersion != '1' ||		    (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {			printk(KERN_ERR "  Unknown ST Microelectronics"			       " Extended Query version %c.%c.\n",			       extp->MajorVersion, extp->MinorVersion);			kfree(extp);			return NULL;		}		/* Do some byteswapping if necessary */		extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);		extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);#ifdef DEBUG_CFI_FEATURES		/* Tell the user about it in lots of lovely detail */		cfi_tell_features(extp);#endif		/* Install our own private info structure */		cfi->cmdset_priv = extp;	}	for (i=0; i< cfi->numchips; i++) {		cfi->chips[i].word_write_time = 128;		cfi->chips[i].buffer_write_time = 128;		cfi->chips[i].erase_time = 1024;	}	return cfi_staa_setup(map);}static struct mtd_info *cfi_staa_setup(struct map_info *map){	struct cfi_private *cfi = map->fldrv_priv;	struct mtd_info *mtd;	unsigned long offset = 0;	int i,j;	unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);	//printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);	if (!mtd) {		printk(KERN_ERR "Failed to allocate memory for MTD device\n");		kfree(cfi->cmdset_priv);		return NULL;	}	memset(mtd, 0, sizeof(*mtd));	mtd->priv = map;	mtd->type = MTD_NORFLASH;	mtd->size = devsize * cfi->numchips;	mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)			* mtd->numeraseregions, GFP_KERNEL);	if (!mtd->eraseregions) {		printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");		kfree(cfi->cmdset_priv);		kfree(mtd);		return NULL;	}	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {		unsigned long ernum, ersize;		ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;		ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;		if (mtd->erasesize < ersize) {			mtd->erasesize = ersize;		}		for (j=0; j<cfi->numchips; j++) {			mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;			mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;			mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;		}		offset += (ersize * ernum);		}		if (offset != devsize) {			/* Argh */			printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);			kfree(mtd->eraseregions);			kfree(cfi->cmdset_priv);			kfree(mtd);			return NULL;		}		for (i=0; i<mtd->numeraseregions;i++){			printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n",			       i,mtd->eraseregions[i].offset,			       mtd->eraseregions[i].erasesize,			       mtd->eraseregions[i].numblocks);		}	/* Also select the correct geometry setup too */	mtd->erase = cfi_staa_erase_varsize;	mtd->read = cfi_staa_read;        mtd->write = cfi_staa_write_buffers;	mtd->writev = cfi_staa_writev;	mtd->sync = cfi_staa_sync;	mtd->lock = cfi_staa_lock;	mtd->unlock = cfi_staa_unlock;	mtd->suspend = cfi_staa_suspend;	mtd->resume = cfi_staa_resume;	mtd->flags = MTD_CAP_NORFLASH;	mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */	mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */	map->fldrv = &cfi_staa_chipdrv;	__module_get(THIS_MODULE);	mtd->name = map->name;	return mtd;}static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf){	map_word status, status_OK;	unsigned long timeo;	DECLARE_WAITQUEUE(wait, current);	int suspended = 0;	unsigned long cmd_addr;	struct cfi_private *cfi = map->fldrv_priv;	adr += chip->start;	/* Ensure cmd read/writes are aligned. */	cmd_addr = adr & ~(map_bankwidth(map)-1);	/* Let's determine this according to the interleave only once */	status_OK = CMD(0x80);	timeo = jiffies + HZ; retry:	spin_lock_bh(chip->mutex);	/* Check that the chip's ready to talk to us.	 * If it's in FL_ERASING state, suspend it and make it talk now.	 */	switch (chip->state) {	case FL_ERASING:		if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))			goto sleep; /* We don't support erase suspend */		map_write (map, CMD(0xb0), cmd_addr);		/* If the flash has finished erasing, then 'erase suspend'		 * appears to make some (28F320) flash devices switch to		 * 'read' mode.  Make sure that we switch to 'read status'		 * mode so we get the right data. --rmk		 */		map_write(map, CMD(0x70), cmd_addr);		chip->oldstate = FL_ERASING;		chip->state = FL_ERASE_SUSPENDING;		//		printk("Erase suspending at 0x%lx\n", cmd_addr);		for (;;) {			status = map_read(map, cmd_addr);			if (map_word_andequal(map, status, status_OK, status_OK))				break;			if (time_after(jiffies, timeo)) {				/* Urgh */				map_write(map, CMD(0xd0), cmd_addr);				/* make sure we're in 'read status' mode */				map_write(map, CMD(0x70), cmd_addr);				chip->state = FL_ERASING;				spin_unlock_bh(chip->mutex);				printk(KERN_ERR "Chip not ready after erase "				       "suspended: status = 0x%lx\n", status.x[0]);				return -EIO;			}			spin_unlock_bh(chip->mutex);			cfi_udelay(1);			spin_lock_bh(chip->mutex);		}		suspended = 1;		map_write(map, CMD(0xff), cmd_addr);		chip->state = FL_READY;		break;#if 0	case FL_WRITING:		/* Not quite yet */#endif	case FL_READY:		break;	case FL_CFI_QUERY:	case FL_JEDEC_QUERY:		map_write(map, CMD(0x70), cmd_addr);		chip->state = FL_STATUS;	case FL_STATUS:		status = map_read(map, cmd_addr);		if (map_word_andequal(map, status, status_OK, status_OK)) {			map_write(map, CMD(0xff), cmd_addr);			chip->state = FL_READY;			break;		}		/* Urgh. Chip not yet ready to talk to us. */		if (time_after(jiffies, timeo)) {			spin_unlock_bh(chip->mutex);			printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %lx\n", status.x[0]);			return -EIO;		}		/* Latency issues. Drop the lock, wait a while and retry */		spin_unlock_bh(chip->mutex);		cfi_udelay(1);		goto retry;	default:	sleep:		/* Stick ourselves on a wait queue to be woken when		   someone changes the status */		set_current_state(TASK_UNINTERRUPTIBLE);		add_wait_queue(&chip->wq, &wait);		spin_unlock_bh(chip->mutex);		schedule();		remove_wait_queue(&chip->wq, &wait);		timeo = jiffies + HZ;		goto retry;	}	map_copy_from(map, buf, adr, len);	if (suspended) {		chip->state = chip->oldstate;		/* What if one interleaved chip has finished and the		   other hasn't? The old code would leave the finished		   one in READY mode. That's bad, and caused -EROFS		   errors to be returned from do_erase_oneblock because		   that's the only bit it checked for at the time.		   As the state machine appears to explicitly allow		   sending the 0x70 (Read Status) command to an erasing		   chip and expecting it to be ignored, that's what we		   do. */		map_write(map, CMD(0xd0), cmd_addr);		map_write(map, CMD(0x70), cmd_addr);	}	wake_up(&chip->wq);	spin_unlock_bh(chip->mutex);	return 0;}static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf){	struct map_info *map = mtd->priv;	struct cfi_private *cfi = map->fldrv_priv;	unsigned long ofs;	int chipnum;	int ret = 0;	/* ofs: offset within the first chip that the first read should start */	chipnum = (from >> cfi->chipshift);	ofs = from - (chipnum <<  cfi->chipshift);	*retlen = 0;	while (len) {		unsigned long thislen;		if (chipnum >= cfi->numchips)			break;		if ((len + ofs -1) >> cfi->chipshift)			thislen = (1<<cfi->chipshift) - ofs;		else			thislen = len;		ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);		if (ret)			break;		*retlen += thislen;		len -= thislen;		buf += thislen;		ofs = 0;		chipnum++;	}	return ret;}static inline int do_write_buffer(struct map_info *map, struct flchip *chip,				  unsigned long adr, const u_char *buf, int len){	struct cfi_private *cfi = map->fldrv_priv;	map_word status, status_OK;	unsigned long cmd_adr, timeo;	DECLARE_WAITQUEUE(wait, current);	int wbufsize, z;        /* M58LW064A requires bus alignment for buffer wriets -- saw */        if (adr & (map_bankwidth(map)-1))            return -EINVAL;        wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;        adr += chip->start;	cmd_adr = adr & ~(wbufsize-1);	/* Let's determine this according to the interleave only once */        status_OK = CMD(0x80);	timeo = jiffies + HZ; retry:#ifdef DEBUG_CFI_FEATURES       printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);#endif	spin_lock_bh(chip->mutex);	/* Check that the chip's ready to talk to us.	 * Later, we can actually think about interrupting it	 * if it's in FL_ERASING state.	 * Not just yet, though.	 */	switch (chip->state) {	case FL_READY:		break;	case FL_CFI_QUERY:	case FL_JEDEC_QUERY:		map_write(map, CMD(0x70), cmd_adr);                chip->state = FL_STATUS;#ifdef DEBUG_CFI_FEATURES        printk("%s: 1 status[%x]\n", __FUNCTION__, map_read(map, cmd_adr));#endif	case FL_STATUS:		status = map_read(map, cmd_adr);		if (map_word_andequal(map, status, status_OK, status_OK))			break;		/* Urgh. Chip not yet ready to talk to us. */		if (time_after(jiffies, timeo)) {			spin_unlock_bh(chip->mutex);                        printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %lx, status = %lx\n",                               status.x[0], map_read(map, cmd_adr).x[0]);			return -EIO;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品一级在线| 欧美日韩一区二区三区免费看 | 亚洲五码中文字幕| 日韩一区二区三区精品视频| 乱一区二区av| 亚洲免费观看视频| 久久久五月婷婷| 在线免费观看不卡av| 久久精品无码一区二区三区| 欧美色图一区二区三区| 国产一区二区不卡老阿姨| 亚洲电影在线播放| 337p粉嫩大胆噜噜噜噜噜91av| 99久久综合国产精品| 美腿丝袜在线亚洲一区| 一区二区三区中文在线| 中文字幕国产一区二区| 日韩欧美123| 欧美怡红院视频| 高清不卡在线观看av| 久久精品国产在热久久| 精品国产髙清在线看国产毛片| 在线看不卡av| 91偷拍与自偷拍精品| 国产综合久久久久久鬼色| 婷婷夜色潮精品综合在线| 日韩理论片中文av| 久久精品日产第一区二区三区高清版| 国产美女娇喘av呻吟久久| 图片区小说区区亚洲影院| 亚洲女子a中天字幕| 国产精品久久久久影院亚瑟| 555夜色666亚洲国产免| 91黄色免费版| 欧美亚洲国产一区二区三区va| 国产高清亚洲一区| 国产精品中文字幕欧美| 韩国视频一区二区| 老司机一区二区| 久久国产人妖系列| 精品亚洲aⅴ乱码一区二区三区| 久久精品国产免费看久久精品| 青青草伊人久久| 日本特黄久久久高潮| 成人激情小说网站| 日韩一级片网址| 亚洲精品高清在线观看| 国内精品国产成人国产三级粉色| 一本久道中文字幕精品亚洲嫩| 欧美成人a∨高清免费观看| 亚洲色图欧美在线| 国产一区二区三区国产| 欧美日韩日日摸| 最新国产精品久久精品| 狠狠网亚洲精品| 69堂精品视频| 一区二区三区**美女毛片| 国产盗摄一区二区三区| 欧美精品在线观看播放| 中文字幕欧美一| 国产成人一区在线| 欧美精品一区二区三区视频| 亚洲午夜成aⅴ人片| 国产传媒欧美日韩成人| 在线观看91精品国产麻豆| 亚洲视频图片小说| 成人黄色a**站在线观看| 精品粉嫩超白一线天av| 三级欧美韩日大片在线看| 一本到三区不卡视频| 中文一区在线播放| 国产乱子轮精品视频| 91精品国产综合久久福利| 亚洲国产综合在线| 欧美自拍偷拍一区| 亚洲三级免费电影| 99久久99久久久精品齐齐| 国产日韩欧美一区二区三区乱码| 麻豆成人在线观看| 91精品国产美女浴室洗澡无遮挡| 一区二区三区四区中文字幕| 99久久国产综合色|国产精品| 亚洲国产成人一区二区三区| 国产91精品在线观看| 久久精品一区二区三区四区| 国产一区二区视频在线播放| 久久免费偷拍视频| 国产精品羞羞答答xxdd| 亚洲精品一区二区三区香蕉| 精品系列免费在线观看| 久久久99久久精品欧美| 成人sese在线| 亚洲精品成a人| 欧美性生活久久| 日产欧产美韩系列久久99| 欧美不卡一二三| 国产一区二区三区美女| 综合激情网...| 欧美日韩一区 二区 三区 久久精品| 洋洋成人永久网站入口| 欧美日韩国产影片| 另类中文字幕网| 国产欧美日韩另类一区| 91成人免费网站| 美女视频一区二区三区| 久久综合久色欧美综合狠狠| 成人高清免费观看| 亚洲成人黄色影院| 久久综合国产精品| 色视频一区二区| 看电影不卡的网站| 中文字幕亚洲欧美在线不卡| 在线观看视频91| 国产乱妇无码大片在线观看| 最新热久久免费视频| 欧美一区二区三区四区五区| 国产a视频精品免费观看| 一区二区三区中文字幕在线观看| 欧美一区二区三区视频| 国产精品99久久久久久久女警| 欧美伦理电影网| 国产成人夜色高潮福利影视| 亚洲女同一区二区| 欧美精品一区二| 99久久婷婷国产| 日韩1区2区日韩1区2区| 亚洲视频1区2区| 欧美精品成人一区二区三区四区| 国产91丝袜在线18| 日韩极品在线观看| 国产欧美一区在线| 欧美高清视频一二三区| 99精品桃花视频在线观看| 日本不卡在线视频| 国产精品毛片久久久久久久| 91精品在线免费| 在线观看日韩电影| 成人黄色在线看| 韩国av一区二区三区在线观看| 国产精品嫩草99a| 日韩三级在线观看| 91黄色在线观看| 成人午夜电影小说| 青青草成人在线观看| 一个色综合av| 国产精品私人影院| 精品国精品国产尤物美女| 色婷婷激情综合| 丁香五精品蜜臀久久久久99网站 | 亚洲精品亚洲人成人网在线播放| 日韩三级视频在线观看| 欧美自拍丝袜亚洲| 欧美亚洲自拍偷拍| 粗大黑人巨茎大战欧美成人| 国产一区 二区 三区一级| 美国十次了思思久久精品导航| 香蕉成人啪国产精品视频综合网| 一区二区三区中文在线| 亚洲一区二区中文在线| 亚洲精品国产a| 亚洲国产日产av| 日韩和欧美的一区| 日日骚欧美日韩| 日产欧产美韩系列久久99| 蜜桃一区二区三区在线| 日韩av不卡在线观看| 日本系列欧美系列| 国产在线视频不卡二| 国产精品一二一区| 国产麻豆9l精品三级站| 成人精品电影在线观看| av在线免费不卡| 一本到高清视频免费精品| 日本高清成人免费播放| 欧美性色黄大片手机版| 欧美军同video69gay| 日韩一区二区三区免费看 | 91精品国产综合久久久久久 | 国产在线视视频有精品| 国产成人免费视频一区| 99免费精品视频| 欧美色成人综合| 91精品午夜视频| 欧美va亚洲va国产综合| 久久精品一区二区三区四区 | 色综合天天性综合| 欧美午夜不卡视频| www国产成人免费观看视频 深夜成人网| 精品毛片乱码1区2区3区| 国产亚洲一区字幕| 亚洲综合男人的天堂| 三级亚洲高清视频| 成人中文字幕电影| 欧美福利视频导航| 国产网站一区二区三区| 一区二区高清在线| 国产自产视频一区二区三区| 色综合激情五月| 26uuu欧美| 亚洲成人自拍偷拍|