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

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

?? cfi_cmdset_0020.c

?? 根據fs2410移植過后的mtd驅動源碼
?? 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免费一区二区三区试看| 从欧美一区二区三区| 日韩高清中文字幕一区| 悠悠色在线精品| 亚洲欧美在线另类| 欧美三级三级三级| 风间由美一区二区三区在线观看| 99国产一区二区三精品乱码| 欧美videossexotv100| 在线观看视频一区二区| 久久亚洲二区三区| 亚洲天堂av老司机| 亚洲高清在线精品| 在线影院国内精品| 亚洲乱码国产乱码精品精可以看| 91日韩在线专区| 亚洲综合网站在线观看| 欧美一区二区三区喷汁尤物| 国产真实乱对白精彩久久| 久久久99久久精品欧美| 99热99精品| 色菇凉天天综合网| 国产精品网曝门| 久久久亚洲综合| 日韩一级二级三级| 久久久99免费| 国产精品久久久久aaaa樱花| 国产日产欧美一区| 国产三区在线成人av| 国产精品久久久久一区| 亚洲制服丝袜av| 欧美xxx久久| 欧美午夜片在线看| 精品国偷自产国产一区| 欧美一级艳片视频免费观看| 久久久久久久久蜜桃| 美女网站一区二区| 亚洲同性同志一二三专区| 欧美日韩成人综合在线一区二区| 美女精品一区二区| 亚洲日本在线看| 欧美一区二区三区免费大片| 白白色亚洲国产精品| 日本免费新一区视频| 中文字幕一区二区三区av | 久久天堂av综合合色蜜桃网| 色综合咪咪久久| 一区二区三区四区乱视频| 97超碰欧美中文字幕| 伊人一区二区三区| 中文字幕 久热精品 视频在线| 国产精品一线二线三线精华| 国产成人亚洲综合a∨婷婷| 国产成人免费视频网站高清观看视频| av影院午夜一区| 久久日一线二线三线suv| 国产99久久久精品| 日韩欧美一区二区在线视频| 国内精品免费在线观看| 国产精品久久久久久亚洲毛片| 成人精品鲁一区一区二区| 午夜精品成人在线视频| 国产欧美日韩三区| 日韩一区二区在线免费观看| 91免费看`日韩一区二区| 久久精品国产一区二区三| 伊人一区二区三区| 欧美国产日韩a欧美在线观看| 在线不卡的av| 色婷婷精品大在线视频| 成人做爰69片免费看网站| 久久成人免费电影| 免费成人你懂的| 日本亚洲天堂网| 水野朝阳av一区二区三区| 在线精品视频小说1| 国产亚洲精品中文字幕| 91原创在线视频| 日韩高清电影一区| 玉米视频成人免费看| 日韩视频一区二区| 国产99久久精品| 国产一区二区成人久久免费影院| 青青草国产精品亚洲专区无| 一区二区三区免费看视频| 色播五月激情综合网| 日本一区中文字幕| 日韩精品一级中文字幕精品视频免费观看 | 美女国产一区二区| 午夜精品久久久久久久久久久 | 久久精品国产亚洲高清剧情介绍 | 91福利区一区二区三区| 国产成人在线网站| 成人黄色小视频| 日本乱人伦aⅴ精品| 欧美视频第二页| 欧美性大战久久久| 欧美肥妇bbw| 亚洲精品在线三区| 一色屋精品亚洲香蕉网站| 一区二区三区在线观看欧美| 午夜免费欧美电影| 国产一区二区三区观看| 91蜜桃网址入口| 日韩一级完整毛片| 国产欧美视频一区二区| 亚洲综合色成人| 国产精品一二三区| 欧洲视频一区二区| 欧美国产禁国产网站cc| 亚洲成人免费电影| 成人高清av在线| 欧美一级日韩一级| 亚洲国产精品久久人人爱蜜臀 | 久久久久青草大香线综合精品| 国产精品欧美一区二区三区| 亚洲mv在线观看| 成人开心网精品视频| 日韩视频一区二区在线观看| 亚洲人成网站色在线观看| 免费日本视频一区| 欧美视频在线不卡| 综合久久一区二区三区| 另类综合日韩欧美亚洲| 91精品久久久久久蜜臀| 亚洲美女屁股眼交3| 91美女视频网站| 国产精品电影一区二区三区| 国产成人精品影视| 国产精品久久久99| k8久久久一区二区三区| 亚洲国产精华液网站w| 成人app网站| 亚洲国产人成综合网站| 欧美人牲a欧美精品| 国产精品久久毛片| 成人国产视频在线观看| 亚洲图片激情小说| 欧美日韩成人一区| 国产一区三区三区| 国产精品免费视频一区| 日本精品免费观看高清观看| 亚洲免费在线电影| 欧美夫妻性生活| 国精产品一区一区三区mba视频| 国产日韩欧美亚洲| 欧美亚洲动漫精品| 紧缚奴在线一区二区三区| 日本一区二区三区高清不卡| 99久久综合色| 国产在线视视频有精品| 亚洲人成精品久久久久久| 91精品国产美女浴室洗澡无遮挡| 国产精品 日产精品 欧美精品| 亚洲视频一二区| 精品久久久久久久久久久院品网| 色噜噜狠狠色综合中国| 国产精品一区二区视频| 亚洲va欧美va天堂v国产综合| 国产欧美一区二区精品久导航| 在线精品视频小说1| 豆国产96在线|亚洲| 蜜乳av一区二区三区| 亚洲成人资源在线| 一区二区三区精品在线观看| 久久久久国产精品麻豆| 欧美日本韩国一区| 在线观看国产91| 欧洲av一区二区嗯嗯嗯啊| 成人av一区二区三区| 国产91清纯白嫩初高中在线观看| 麻豆成人久久精品二区三区红| 亚洲主播在线播放| 亚洲成a天堂v人片| 亚洲高清久久久| 亚洲高清免费观看| 爽好久久久欧美精品| 日韩精品亚洲一区二区三区免费| 亚洲男女毛片无遮挡| 亚洲国产婷婷综合在线精品| 亚洲电影一区二区| 日韩国产在线观看一区| 日本va欧美va精品发布| 麻豆视频观看网址久久| 国产成人精品网址| 99久久精品免费看国产免费软件| 成年人午夜久久久| 欧美视频完全免费看| 成人美女视频在线看| 91婷婷韩国欧美一区二区| 一本大道久久a久久综合婷婷| 欧美羞羞免费网站| 欧美mv和日韩mv国产网站| 国产精品视频yy9299一区| 亚洲主播在线播放| 国产一区二区不卡| 色噜噜狠狠一区二区三区果冻| 日韩欧美成人激情| 亚洲天堂免费在线观看视频|