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

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

?? jedec.c

?? 根據fs2410移植過后的mtd驅動源碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* JEDEC Flash Interface. * This is an older type of interface for self programming flash. It is * commonly use in older AMD chips and is obsolete compared with CFI. * It is called JEDEC because the JEDEC association distributes the ID codes * for the chips. * * See the AMD flash databook for information on how to operate the interface. * * This code does not support anything wider than 8 bit flash chips, I am * not going to guess how to send commands to them, plus I expect they will * all speak CFI.. * * $Id: jedec.c,v 1.22 2005/01/05 18:05:11 dwmw2 Exp $ */#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/mtd/jedec.h>#include <linux/mtd/map.h>#include <linux/mtd/mtd.h>#include <linux/mtd/compatmac.h>static struct mtd_info *jedec_probe(struct map_info *);static int jedec_probe8(struct map_info *map,unsigned long base,		  struct jedec_private *priv);static int jedec_probe16(struct map_info *map,unsigned long base,		  struct jedec_private *priv);static int jedec_probe32(struct map_info *map,unsigned long base,		  struct jedec_private *priv);static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,			    unsigned long len);static int flash_erase(struct mtd_info *mtd, struct erase_info *instr);static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,		       size_t *retlen, const u_char *buf);static unsigned long my_bank_size;/* Listing of parts and sizes. We need this table to learn the sector   size of the chip and the total length */static const struct JEDECTable JEDEC_table[] = {	{		.jedec		= 0x013D,		.name		= "AMD Am29F017D",		.size		= 2*1024*1024,		.sectorsize	= 64*1024,		.capabilities	= MTD_CAP_NORFLASH	},	{		.jedec		= 0x01AD,		.name		= "AMD Am29F016",		.size		= 2*1024*1024,		.sectorsize	= 64*1024,		.capabilities	= MTD_CAP_NORFLASH	},	{		.jedec		= 0x01D5,		.name		= "AMD Am29F080",		.size		= 1*1024*1024,		.sectorsize	= 64*1024,		.capabilities	= MTD_CAP_NORFLASH	},	{		.jedec		= 0x01A4,		.name		= "AMD Am29F040",		.size		= 512*1024,		.sectorsize	= 64*1024,		.capabilities	= MTD_CAP_NORFLASH	},	{		.jedec		= 0x20E3,		.name		= "AMD Am29W040B",		.size		= 512*1024,		.sectorsize	= 64*1024,		.capabilities	= MTD_CAP_NORFLASH	},	{		.jedec		= 0xC2AD,		.name		= "Macronix MX29F016",		.size		= 2*1024*1024,		.sectorsize	= 64*1024,		.capabilities	= MTD_CAP_NORFLASH	},	{ .jedec = 0x0 }};static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);static void jedec_sync(struct mtd_info *mtd) {};static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,		      size_t *retlen, u_char *buf);static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,			     size_t *retlen, u_char *buf);static struct mtd_info *jedec_probe(struct map_info *map);static struct mtd_chip_driver jedec_chipdrv = {	.probe	= jedec_probe,	.name	= "jedec",	.module	= THIS_MODULE};/* Probe entry point */static struct mtd_info *jedec_probe(struct map_info *map){   struct mtd_info *MTD;   struct jedec_private *priv;   unsigned long Base;   unsigned long SectorSize;   unsigned count;   unsigned I,Uniq;   char Part[200];   memset(&priv,0,sizeof(priv));   MTD = kmalloc(sizeof(struct mtd_info) + sizeof(struct jedec_private), GFP_KERNEL);   if (!MTD)	   return NULL;   memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));   priv = (struct jedec_private *)&MTD[1];   my_bank_size = map->size;   if (map->size/my_bank_size > MAX_JEDEC_CHIPS)   {      printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");      kfree(MTD);      return NULL;   }   for (Base = 0; Base < map->size; Base += my_bank_size)   {      // Perhaps zero could designate all tests?      if (map->buswidth == 0)	 map->buswidth = 1;      if (map->buswidth == 1){	 if (jedec_probe8(map,Base,priv) == 0) {		 printk("did recognize jedec chip\n");		 kfree(MTD);	         return NULL;	 }      }      if (map->buswidth == 2)	 jedec_probe16(map,Base,priv);      if (map->buswidth == 4)	 jedec_probe32(map,Base,priv);   }   // Get the biggest sector size   SectorSize = 0;   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)   {	   //	   printk("priv->chips[%d].jedec is %x\n",I,priv->chips[I].jedec);	   //	   printk("priv->chips[%d].sectorsize is %lx\n",I,priv->chips[I].sectorsize);      if (priv->chips[I].sectorsize > SectorSize)	 SectorSize = priv->chips[I].sectorsize;   }   // Quickly ensure that the other sector sizes are factors of the largest   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)   {      if ((SectorSize/priv->chips[I].sectorsize)*priv->chips[I].sectorsize != SectorSize)      {	 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");	 kfree(MTD);	 return NULL;      }   }   /* Generate a part name that includes the number of different chips and      other configuration information */   count = 1;   strlcpy(Part,map->name,sizeof(Part)-10);   strcat(Part," ");   Uniq = 0;   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)   {      const struct JEDECTable *JEDEC;      if (priv->chips[I+1].jedec == priv->chips[I].jedec)      {	 count++;	 continue;      }      // Locate the chip in the jedec table      JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);      if (JEDEC == 0)      {	 printk("mtd: Internal Error, JEDEC not set\n");	 kfree(MTD);	 return NULL;      }      if (Uniq != 0)	 strcat(Part,",");      Uniq++;      if (count != 1)	 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);      else	 sprintf(Part+strlen(Part),"%s",JEDEC->name);      if (strlen(Part) > sizeof(Part)*2/3)	 break;      count = 1;   }   /* Determine if the chips are organized in a linear fashion, or if there      are empty banks. Note, the last bank does not count here, only the      first banks are important. Holes on non-bank boundaries can not exist      due to the way the detection algorithm works. */   if (priv->size < my_bank_size)      my_bank_size = priv->size;   priv->is_banked = 0;   //printk("priv->size is %x, my_bank_size is %x\n",priv->size,my_bank_size);   //printk("priv->bank_fill[0] is %x\n",priv->bank_fill[0]);   if (!priv->size) {	   printk("priv->size is zero\n");	   kfree(MTD);	   return NULL;   }   if (priv->size/my_bank_size) {	   if (priv->size/my_bank_size == 1) {		   priv->size = my_bank_size;	   }	   else {		   for (I = 0; I != priv->size/my_bank_size - 1; I++)		   {		      if (priv->bank_fill[I] != my_bank_size)			 priv->is_banked = 1;		      /* This even could be eliminated, but new de-optimized read/write			 functions have to be written */		      printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);		      if (priv->bank_fill[I] != priv->bank_fill[0])		      {			 printk("mtd: Failed. Cannot handle unsymmetric banking\n");			 kfree(MTD);			 return NULL;		      }		   }	   }   }   if (priv->is_banked == 1)      strcat(Part,", banked");   //   printk("Part: '%s'\n",Part);   memset(MTD,0,sizeof(*MTD));  // strlcpy(MTD->name,Part,sizeof(MTD->name));   MTD->name = map->name;   MTD->type = MTD_NORFLASH;   MTD->flags = MTD_CAP_NORFLASH;   MTD->erasesize = SectorSize*(map->buswidth);   //   printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize);   MTD->size = priv->size;   //   printk("MTD->size is %x\n",(unsigned int)MTD->size);   //MTD->module = THIS_MODULE; // ? Maybe this should be the low level module?   MTD->erase = flash_erase;   if (priv->is_banked == 1)      MTD->read = jedec_read_banked;   else      MTD->read = jedec_read;   MTD->write = flash_write;   MTD->sync = jedec_sync;   MTD->priv = map;   map->fldrv_priv = priv;   map->fldrv = &jedec_chipdrv;   __module_get(THIS_MODULE);   return MTD;}/* Helper for the JEDEC function, JEDEC numbers all have odd parity */static int checkparity(u_char C){   u_char parity = 0;   while (C != 0)   {      parity ^= C & 1;      C >>= 1;   }   return parity == 1;}/* Take an array of JEDEC numbers that represent interleved flash chips   and process them. Check to make sure they are good JEDEC numbers, look   them up and then add them to the chip list */static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,		  unsigned long base,struct jedec_private *priv){   unsigned I,J;   unsigned long Size;   unsigned long SectorSize;   const struct JEDECTable *JEDEC;   // Test #2 JEDEC numbers exhibit odd parity   for (I = 0; I != Count; I++)   {      if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)	 return 0;   }   // Finally, just make sure all the chip sizes are the same   JEDEC = jedec_idtoinf(Mfg[0],Id[0]);   if (JEDEC == 0)   {      printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);      return 0;   }   Size = JEDEC->size;   SectorSize = JEDEC->sectorsize;   for (I = 0; I != Count; I++)   {      JEDEC = jedec_idtoinf(Mfg[0],Id[0]);      if (JEDEC == 0)      {	 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);	 return 0;      }      if (Size != JEDEC->size || SectorSize != JEDEC->sectorsize)      {	 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");	 return 0;      }   }   // Load the Chips   for (I = 0; I != MAX_JEDEC_CHIPS; I++)   {      if (priv->chips[I].jedec == 0)	 break;   }   if (I + Count > MAX_JEDEC_CHIPS)   {      printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");      return 0;   }   // Add them to the table   for (J = 0; J != Count; J++)   {      unsigned long Bank;      JEDEC = jedec_idtoinf(Mfg[J],Id[J]);      priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];      priv->chips[I].size = JEDEC->size;      priv->chips[I].sectorsize = JEDEC->sectorsize;      priv->chips[I].base = base + J;      priv->chips[I].datashift = J*8;      priv->chips[I].capabilities = JEDEC->capabilities;      priv->chips[I].offset = priv->size + J;      // log2 n :|      priv->chips[I].addrshift = 0;      for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);      // Determine how filled this bank is.      Bank = base & (~(my_bank_size-1));      if (priv->bank_fill[Bank/my_bank_size] < base +	  (JEDEC->size << priv->chips[I].addrshift) - Bank)	 priv->bank_fill[Bank/my_bank_size] =  base + (JEDEC->size << priv->chips[I].addrshift) - Bank;      I++;   }   priv->size += priv->chips[I-1].size*Count;   return priv->chips[I-1].size;}/* Lookup the chip information from the JEDEC ID table. */static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id){   __u16 Id = (mfr << 8) | id;   unsigned long I = 0;   for (I = 0; JEDEC_table[I].jedec != 0; I++)      if (JEDEC_table[I].jedec == Id)	 return JEDEC_table + I;   return NULL;}// Look for flash using an 8 bit bus interfacestatic int jedec_probe8(struct map_info *map,unsigned long base,		  struct jedec_private *priv){   #define flread(x) map_read8(map,base+x)   #define flwrite(v,x) map_write8(map,v,base+x)   const unsigned long AutoSel1 = 0xAA;   const unsigned long AutoSel2 = 0x55;   const unsigned long AutoSel3 = 0x90;   const unsigned long Reset = 0xF0;   __u32 OldVal;   __u8 Mfg[1];   __u8 Id[1];   unsigned I;   unsigned long Size;   // Wait for any write/erase operation to settle   OldVal = flread(base);   for (I = 0; OldVal != flread(base) && I < 10000; I++)      OldVal = flread(base);   // Reset the chip   flwrite(Reset,0x555);   // Send the sequence   flwrite(AutoSel1,0x555);   flwrite(AutoSel2,0x2AA);   flwrite(AutoSel3,0x555);   //  Get the JEDEC numbers   Mfg[0] = flread(0);   Id[0] = flread(1);   //   printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);   Size = handle_jedecs(map,Mfg,Id,1,base,priv);   //   printk("handle_jedecs Size is %x\n",(unsigned int)Size);   if (Size == 0)   {      flwrite(Reset,0x555);      return 0;   }   // Reset.   flwrite(Reset,0x555);   return 1;   #undef flread   #undef flwrite}// Look for flash using a 16 bit bus interface (ie 2 8-bit chips)static int jedec_probe16(struct map_info *map,unsigned long base,		  struct jedec_private *priv){   return 0;}// Look for flash using a 32 bit bus interface (ie 4 8-bit chips)static int jedec_probe32(struct map_info *map,unsigned long base,		  struct jedec_private *priv){   #define flread(x) map_read32(map,base+((x)<<2))   #define flwrite(v,x) map_write32(map,v,base+((x)<<2))   const unsigned long AutoSel1 = 0xAAAAAAAA;   const unsigned long AutoSel2 = 0x55555555;   const unsigned long AutoSel3 = 0x90909090;   const unsigned long Reset = 0xF0F0F0F0;   __u32 OldVal;   __u8 Mfg[4];   __u8 Id[4];   unsigned I;   unsigned long Size;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产剧情在线观看一区二区| 欧美一区二区三区视频免费| 粉嫩av亚洲一区二区图片| 免费成人在线影院| 亚洲成人免费电影| 天堂蜜桃91精品| 欧美aaaaa成人免费观看视频| 日韩av网站免费在线| 日韩av在线发布| 另类欧美日韩国产在线| 极品少妇xxxx精品少妇偷拍| 老司机精品视频一区二区三区| 免费观看在线色综合| 理论电影国产精品| 国产精品99久久久久久有的能看 | 国产成人av影院| 成人av午夜电影| 91亚洲大成网污www| 日本韩国欧美三级| 欧美日韩一区二区三区视频| 69p69国产精品| 精品国产精品网麻豆系列| 国产婷婷色一区二区三区四区| 国产精品久久久久永久免费观看| 亚洲日本在线a| 视频一区视频二区中文字幕| 精品一区二区三区视频在线观看| 豆国产96在线|亚洲| 日本高清不卡在线观看| 欧美男人的天堂一二区| 欧美变态口味重另类| 国产婷婷一区二区| 亚洲午夜三级在线| 久久精品久久99精品久久| 高清不卡在线观看| 欧美系列日韩一区| 精品久久久久香蕉网| 综合在线观看色| 日韩精品电影一区亚洲| 韩国理伦片一区二区三区在线播放 | 中文字幕亚洲精品在线观看| 亚洲免费av在线| 麻豆精品精品国产自在97香蕉| 成人精品亚洲人成在线| 欧美性大战久久| 久久精品无码一区二区三区| 有码一区二区三区| 国内国产精品久久| 一本久久a久久免费精品不卡| 777奇米四色成人影色区| 国产欧美日韩精品a在线观看| 亚洲午夜在线电影| 国产91精品精华液一区二区三区| 欧美偷拍一区二区| 日韩理论片网站| 久久99国产精品久久99| 91蜜桃视频在线| 久久久午夜精品理论片中文字幕| 琪琪一区二区三区| 欧美老肥妇做.爰bbww视频| 4438成人网| 国产精品久久久久久久久免费桃花| 香港成人在线视频| 成人一道本在线| 欧美大尺度电影在线| 亚洲乱码国产乱码精品精98午夜 | 亚洲欧洲性图库| 老色鬼精品视频在线观看播放| 91视频免费播放| 久久婷婷国产综合国色天香| 亚洲国产精品久久不卡毛片| www.亚洲人| 久久久久国产一区二区三区四区| 天堂蜜桃91精品| 91福利社在线观看| 国产精品久久久久久久岛一牛影视 | 亚洲欧美电影院| 高清在线观看日韩| 欧美精彩视频一区二区三区| 日韩欧美国产精品一区| 亚洲欧美日韩国产中文在线| 国产麻豆精品视频| 日韩美女视频在线| 午夜av电影一区| 日本高清无吗v一区| 中文字幕五月欧美| 成人国产视频在线观看| 国产色产综合色产在线视频| 精品影院一区二区久久久| 91精品国产欧美一区二区18| 亚洲观看高清完整版在线观看| 一本大道久久a久久综合婷婷 | 亚洲男人天堂一区| 成人黄色在线看| 欧美国产欧美综合| 风间由美一区二区av101| 久久蜜桃av一区二区天堂| 久久97超碰国产精品超碰| 日韩亚洲电影在线| 久草中文综合在线| 精品国产免费人成电影在线观看四季| 日本午夜一本久久久综合| 欧美二区三区的天堂| 日韩一区精品字幕| 欧美一区欧美二区| 蜜乳av一区二区三区| 国产亚洲综合av| 一区二区三区日韩| 日本高清不卡一区| 亚洲韩国精品一区| 久久久久久久久久久久久女国产乱| 日韩av二区在线播放| 日韩视频一区二区三区| 久久99精品久久久久久| 久久亚洲二区三区| 国产成人h网站| 亚洲男同性视频| 在线播放欧美女士性生活| 日韩精品国产欧美| 精品va天堂亚洲国产| 成人一级片网址| 一级特黄大欧美久久久| 欧美日本国产视频| 久久精品av麻豆的观看方式| 国产丝袜在线精品| 一本大道久久a久久综合婷婷| 午夜视频一区二区| 2020国产精品自拍| av在线这里只有精品| 亚洲综合自拍偷拍| 日韩午夜电影av| 成人永久aaa| 亚洲一区二区av电影| 日韩久久精品一区| 岛国一区二区在线观看| 一区二区三区精密机械公司| 日韩视频免费观看高清完整版在线观看 | 春色校园综合激情亚洲| 亚洲欧洲av一区二区三区久久| 欧美伊人久久久久久午夜久久久久| 视频一区国产视频| 久久免费视频色| 在线观看一区日韩| 韩国精品在线观看| 悠悠色在线精品| 精品福利av导航| 色综合一个色综合| 捆绑变态av一区二区三区| 国产精品热久久久久夜色精品三区| 色婷婷狠狠综合| 精品写真视频在线观看| 亚洲激情综合网| 久久亚洲二区三区| 欧美手机在线视频| 国产精品一区二区果冻传媒| 亚洲一区二区三区四区不卡| 久久奇米777| 欧美精品久久99久久在免费线| 成人午夜电影久久影院| 日韩av网站在线观看| 日韩伦理电影网| 久久婷婷国产综合精品青草| 欧美日本精品一区二区三区| eeuss鲁一区二区三区| 久久精品理论片| 99久久99久久综合| 一区在线播放视频| 欧美一区二区女人| 91视频xxxx| 精品一区免费av| 亚洲国产精品久久久男人的天堂 | 蜜臀久久99精品久久久久宅男| 亚洲欧美中日韩| 久久久亚洲欧洲日产国码αv| 欧美日韩精品一区二区天天拍小说| 成人激情开心网| 国产中文字幕一区| 日韩精品五月天| 一区二区在线观看免费| 国产精品热久久久久夜色精品三区| 日韩亚洲电影在线| 欧美精品日韩一本| 91久久精品国产91性色tv| 成人亚洲精品久久久久软件| 国产一区二区在线看| 天天综合天天综合色| 一区二区久久久久| 亚洲日本欧美天堂| 国产精品丝袜久久久久久app| 精品处破学生在线二十三| 欧美男男青年gay1069videost| 在线精品视频小说1| 色偷偷88欧美精品久久久| 豆国产96在线|亚洲| 国产成人午夜精品5599| 国产美女娇喘av呻吟久久| 韩国在线一区二区| 精品一区二区综合| 国内精品久久久久影院一蜜桃| 久久精品99国产国产精|