`
yzd
  • 浏览: 1817020 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

MTD源码分析(1)

 
阅读更多
<p><span style="font-size: medium;">Linux MTD源代码分析</span>
<br>
by jim zeus<br>
vision 0.1</p>
<div style="text-align: left;">If you got any Problem, Suggestion, Advice or Question ,<br>
Please mail to: jimzeus@sina.com.cn<br>
Any correction will be appreciated.<br><br><h1>
<a name="_Toc7862211"><span style="">专有名词:</span>
</a>
</h1>
<p class="MsoNormal"><strong><span lang="EN-US"></span>
</strong>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">1.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">MTD</span>
</strong>
<strong><span style="">:</span>
</strong>
<span lang="EN-US">Memory Technology Device</span>
<span style="">,内存技术设备,</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">2.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">JEDEC</span>
</strong>
<strong><span style="">:</span>
</strong>
<span lang="EN-US">Joint Electron Device Engineering Council</span>
<span style="">,电子电器设备联合会</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">3.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">CFI</span>
</strong>
<strong><span style="">:</span>
</strong>
<span lang="EN-US">Common Flash Interface</span>
<span style="">,通用</span>
<span lang="EN-US">Flash</span>
<span style="">接口,</span>
<span lang="EN-US">Intel</span>
<span style="">发起的一个</span>
<span lang="EN-US">Flash</span>
<span style="">的接口标准</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">4.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">OOB</span>
</strong>
<strong><span style="">:</span>
</strong>
<span lang="EN-US"> out of band</span>
<span style="">,某些内存技术支持</span>
<span lang="EN-US">out-of-band</span>
<span style="">数据——例如,</span>
<span lang="EN-US">NAND flash</span>
<span style="">每</span>
<span lang="EN-US">512</span>
<span style="">字节的块有</span>
<span lang="EN-US">16</span>
<span style="">个字节的</span>
<span lang="EN-US">extra data</span>
<span style="">,用于纠错或元数据。</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">5.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">ECC</span>
</strong>
<strong><span style="">:</span>
</strong>
<span lang="EN-US"> error correction</span>
<span style="">,某些硬件不仅允许对</span>
<span lang="EN-US">flash</span>
<span style="">的访问,也有</span>
<span lang="EN-US">ecc</span>
<span style="">功能,所有</span>
<span lang="EN-US">flash</span>
<span style="">器件都受位交换现象的困扰。在某些情况下,一个比特位会发生反转或被报告反转了,如果此位真的反转了,就要采用</span>
<span lang="EN-US">ECC</span>
<span style="">算法。</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">6.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">erasesize</span>
</strong>
<strong><span style="">:</span>
</strong>
<span style="">一个</span>
<span lang="EN-US">erase</span>
<span style="">命令可以擦除的最小块的尺寸</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">7.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">buswidth</span>
</strong>
<strong><span style="">:</span>
</strong>
<span lang="EN-US">MTD</span>
<span style="">设备的接口总线宽度</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">8.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">interleave</span>
</strong>
<strong><span style="">:</span>
</strong>
<span style="">交错数,几块芯片平行连接成一块芯片,使</span>
<span lang="EN-US">buswidth</span>
<span style="">变大</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">9.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">devicetype</span>
</strong>
<strong><span style="">:</span>
</strong>
<span style="">芯片类型,</span>
<span lang="EN-US">x8</span>
<span style="">、</span>
<span lang="EN-US">x16</span>
<span style="">或者</span>
<span lang="EN-US">x32</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">10.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">NAND</span>
</strong>
<strong><span style="">:</span>
</strong>
<span style="">一种</span>
<span lang="EN-US">Flash</span>
<span style="">技术,参看</span>
<span lang="EN-US">NAND</span>
<span style="">和</span>
<span lang="EN-US">NOR</span>
<span style="">的比较</span>
</p>
<p class="MsoNormal" style=""><strong><span lang="EN-US">11.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
</strong>
<strong><span lang="EN-US">NOR</span>
</strong>
<strong><span style="">:</span>
</strong>
<span style="">一种</span>
<span lang="EN-US">Flash</span>
<span style="">技术,参看</span>
<span lang="EN-US">NAND</span>
<span style="">和</span>
<span lang="EN-US">NOR</span>
<span style="">的比较</span>
<strong></strong>
</p>
<br><h1>
<a name="_Toc7862212"><span lang="EN-US">Linux MTD</span>
</a>
<span><span style="">介绍:</span>
</span>
</h1>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">MTD(memory technology device</span>
<span style="">内存技术设备</span>
<span lang="EN-US">)</span>
<span style="">是用于访问</span>
<span lang="EN-US">memory</span>
<span style="">设备(</span>
<span lang="EN-US">ROM</span>
<span style="">、</span>
<span lang="EN-US">flash</span>
<span style="">)的</span>
<span lang="EN-US">Linux</span>
<span style="">的子系统。</span>
<span lang="EN-US">MTD</span>
<span style="">的主要目的是为了使新的</span>
<span lang="EN-US">memory</span>
<span style="">设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。</span>
<span lang="EN-US">MTD</span>
<span style="">的所有源代码在</span>
<span lang="EN-US">/drivers/mtd</span>
<span style="">子目录下。我将</span>
<span lang="EN-US">CFI</span>
<span style="">接口的</span>
<span lang="EN-US">MTD</span>
<span style="">设备分为四层(从设备节点直到底层硬件驱动),这四层从上到下依次是:设备节点、</span>
<span lang="EN-US">MTD</span>
<span style="">设备层、</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备层和硬件驱动层。</span>
<span id="lblContent" class="n12"><br><img src="http://www.edires.net/sNewsSystem/Files/Images/3660.jpg" border="0" alt=""><br>
图1 Linux MTD 的层次结构<br><br>
具体的NAND闪存驱动是和NAND通用驱动相关联的,要实现一个NAND闪存硬件驱动,需要实现以下部分:初始化函数,硬件相关的设备就绪函数和控制函数,为了灵活起见,还可以实现硬件相关的命令函数、硬件相关的等待函数和硬件ECC函数。 <br></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><strong><span style="">一、</span>
<span lang="EN-US">Flash</span>
</strong>
<strong><span style="">硬件驱动层</span>
</strong>
<span style="">:硬件驱动层负责在</span>
<span lang="EN-US">init</span>
<span style="">时驱动</span>
<span lang="EN-US">Flash</span>
<span style="">硬件,</span>
<span lang="EN-US">Linux MTD</span>
<span style="">设备的</span>
<span lang="EN-US">NOR</span>
<span style=""> </span>
<span lang="EN-US">Flash</span>
<span style="">芯片驱动遵循</span>
<span lang="EN-US">CFI</span>
<span style="">接口标准,其驱动程序位于</span>
<span lang="EN-US">drivers/mtd/chips</span>
<span style="">子目录下。</span>
<span lang="EN-US">NAND</span>
<span style="">型</span>
<span lang="EN-US">Flash</span>
<span style="">的驱动程序则位于</span>
<span lang="EN-US">/drivers/mtd/nand</span>
<span style="">子目录下</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><strong><span style="">二、</span>
<span lang="EN-US">MTD</span>
</strong>
<strong><span style="">原始设备</span>
</strong>
<span style="">:原始设备层有两部分组成,一部分是</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的通用代码,另一部分是各个特定的</span>
<span lang="EN-US">Flash</span>
<span style="">的数据,例如分区。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"><span> </span>
</span>
<span style="">用于描述</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的数据结构是</span>
<span lang="EN-US">mtd_info</span>
<span style="">,这其中定义了大量的关于</span>
<span lang="EN-US">MTD</span>
<span style="">的数据和操作函数。</span>
<span lang="EN-US">mtd_table</span>
<span style="">(</span>
<span lang="EN-US">mtdcore.c</span>
<span style="">)则是所有</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的列表,</span>
<span lang="EN-US">mtd_part</span>
<span style="">(</span>
<span lang="EN-US">mtd_part.c</span>
<span style="">)是用于表示</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备分区的结构,其中包含了</span>
<span lang="EN-US">mtd_info</span>
<span style="">,因为每一个分区都是被看成一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备加在</span>
<span lang="EN-US">mtd_table</span>
<span style="">中的,</span>
<span lang="EN-US">mtd_part.mtd_info</span>
<span style="">中的大部分数据都从该分区的主分区</span>
<span lang="EN-US">mtd_part-&gt;master</span>
<span style="">中获得。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"><span> </span>
</span>
<span style="">在</span>
<span lang="EN-US">drivers/mtd/maps/</span>
<span style="">子目录下存放的是特定的</span>
<span lang="EN-US">flash</span>
<span style="">的数据,每一个文件都描述了一块板子上的</span>
<span lang="EN-US">flash</span>
<span style="">。其中调用</span>
<span lang="EN-US">add_mtd_device()</span>
<span style="">、</span>
<span lang="EN-US">del_mtd_device()</span>
<span style="">建立</span>
<span lang="EN-US">/</span>
<span style="">删除</span>
<span lang="EN-US">mtd_info</span>
<span style="">结构并将其加入</span>
<span lang="EN-US">/</span>
<span style="">删除</span>
<span lang="EN-US">mtd_table</span>
<span style="">(或者调用</span>
<span lang="EN-US">add_mtd_partition()</span>
<span style="">、</span>
<span lang="EN-US">del_mtd_partition()</span>
<span style="">(</span>
<span lang="EN-US">mtdpart.c</span>
<span style="">)建立</span>
<span lang="EN-US">/</span>
<span style="">删除</span>
<span lang="EN-US">mtd_part</span>
<span style="">结构并将</span>
<span lang="EN-US">mtd_part.mtd_info</span>
<span style="">加入</span>
<span lang="EN-US">/</span>
<span style="">删除</span>
<span lang="EN-US">mtd_table </span>
<span style="">中)。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><strong><span style="">三、</span>
<span lang="EN-US">MTD</span>
</strong>
<strong><span style="">设备层</span>
</strong>
<span style="">:基于</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备,</span>
<span lang="EN-US">linux</span>
<span style="">系统可以定义出</span>
<span lang="EN-US">MTD</span>
<span style="">的块设备(主设备号</span>
<span lang="EN-US">31</span>
<span style="">)和字符设备(设备号</span>
<span lang="EN-US">90</span>
<span style="">)。</span>
<span lang="EN-US">MTD</span>
<span style="">字符设备的定义在</span>
<span lang="EN-US">mtdchar.c</span>
<span style="">中实现,通过注册一系列</span>
<span lang="EN-US">file operation</span>
<span style="">函数(</span>
<span lang="EN-US">lseek</span>
<span style="">、</span>
<span lang="EN-US">open</span>
<span style="">、</span>
<span lang="EN-US">close</span>
<span style="">、</span>
<span lang="EN-US">read</span>
<span style="">、</span>
<span lang="EN-US">write</span>
<span style="">)。</span>
<span lang="EN-US">MTD</span>
<span style="">块设备则是定义了一个描述</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的结构</span>
<span lang="EN-US">mtdblk_dev</span>
<span style="">,并声明了一个名为</span>
<span lang="EN-US">mtdblks</span>
<span style="">的指针数组,这数组中的每一个</span>
<span lang="EN-US">mtdblk_dev</span>
<span style="">和</span>
<span lang="EN-US">mtd_table</span>
<span style="">中的每一个</span>
<span lang="EN-US">mtd_info</span>
<span style="">一一对应。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><strong><span style="">四、设备节点</span>
</strong>
<span style="">:通过</span>
<span lang="EN-US">mknod</span>
<span style="">在</span>
<span lang="EN-US">/dev</span>
<span style="">子目录下建立</span>
<span lang="EN-US">MTD</span>
<span style="">字符设备节点(主设备号为</span>
<span lang="EN-US">90</span>
<span style="">)和</span>
<span lang="EN-US">MTD</span>
<span style="">块设备节点(主设备号为</span>
<span lang="EN-US">31</span>
<span style="">),通过访问此设备节点即可访问</span>
<span lang="EN-US">MTD</span>
<span style="">字符设备和块设备。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><strong><span style="">五、根文件系统</span>
</strong>
<span style="">:在</span>
<span lang="EN-US">Bootloader</span>
<span style="">中将</span>
<span lang="EN-US">JFFS</span>
<span style="">(或</span>
<span lang="EN-US">JFFS2</span>
<span style="">)的文件系统映像</span>
<span lang="EN-US">jffs.image</span>
<span style="">(或</span>
<span lang="EN-US">jffs2.img</span>
<span style="">)烧到</span>
<span lang="EN-US">flash</span>
<span style="">的某一个分区中,在</span>
<span lang="EN-US">/arch/arm/mach-your/arch.c</span>
<span style="">文件的</span>
<span lang="EN-US">your_fixup</span>
<span style="">函数中将该分区作为根文件系统挂载。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><strong><span style="">六、文件系统:</span>
</strong>
<span style="">内核启动后,通过</span>
<span lang="EN-US">mount </span>
<span style="">命令可以将</span>
<span lang="EN-US">flash</span>
<span style="">中的其余分区作为文件系统挂载到</span>
<span lang="EN-US">mountpoint</span>
<span style="">上。</span>
</p>
<h5>
<span style="font-size: medium;"><a name="_Toc7862214"><span lang="EN-US">NOR</span>
</a>
<span><span style="">型</span>
<span lang="EN-US">Flash</span>
</span>
<span><span style="">芯片驱动与</span>
<span lang="EN-US">MTD</span>
</span>
<span><span style="">原始设备</span>
</span>
</span>
</h5>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"><span> </span>
</span>
<span style="">所有的</span>
<span lang="EN-US">NOR</span>
<span style="">型</span>
<span lang="EN-US">Flash</span>
<span style="">的驱动(探测</span>
<span lang="EN-US">probe</span>
<span style="">)程序都放在</span>
<span lang="EN-US">drivers/mtd/chips</span>
<span style="">下,一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备可以由一块或者数块相同的</span>
<span lang="EN-US">Flash</span>
<span style="">芯片组成。假设由</span>
<span lang="EN-US">4</span>
<span style="">块</span>
<span lang="EN-US">devicetype</span>
<span style="">为</span>
<span lang="EN-US">x8</span>
<span style="">的</span>
<span lang="EN-US">Flash</span>
<span style="">,每块大小为</span>
<span lang="EN-US">8M</span>
<span style="">,</span>
<span lang="EN-US">interleave</span>
<span style="">为</span>
<span lang="EN-US">2</span>
<span style="">,起始地址为</span>
<span lang="EN-US">0x01000000</span>
<span style="">,地址相连,则构成一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备(</span>
<span lang="EN-US">0x01000000-0x03000000</span>
<span style="">),其中两块</span>
<span lang="EN-US">interleave</span>
<span style="">成一个</span>
<span lang="EN-US">chip</span>
<span style="">,其地址从</span>
<span lang="EN-US">0x01000000</span>
<span style="">到</span>
<span lang="EN-US">0x02000000</span>
<span style="">,另两块</span>
<span lang="EN-US">interleave</span>
<span style="">成一个</span>
<span lang="EN-US">chip</span>
<span style="">,其地址从</span>
<span lang="EN-US">0x02000000</span>
<span style="">到</span>
<span lang="EN-US">0x03000000</span>
<span style="">。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"><span> </span>
</span>
<span style="">请注意,所有组成一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的</span>
<span lang="EN-US">Flash</span>
<span style="">芯片必须是同类型的(无论是</span>
<span lang="EN-US">interleave</span>
<span style="">还是地址相连),在描述</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的数据结构中也只是采用了同一个结构来描述组成它的</span>
<span lang="EN-US">Flash</span>
<span style="">芯片。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span style="margin-left: 156px; margin-top: 14px; width: 147px; height: 169px;">
</span>
</p>
<table border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td style="border: 0.75pt solid black; vertical-align: top;" width="147" height="169" align="left" valign="top">
<span style="">
           
<table style="height: 242px; width: 151px;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<div class="shape" style="padding: 3.6pt 7.2pt;">
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US">Chip#1<span> </span>
<span> </span>
Chip#2</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US">Chip#3 <span> </span>
<span></span>
Chip#4</span>
</p>
</div>
</td>
</tr></tbody></table></span>
</td>
</tr></tbody></table>
<span style="margin-left: 227px; margin-top: 13px; width: 3px; height: 169px;"><img alt="" width="3" height="169"></span>
<span lang="EN-US"><span> </span>
0x03000000</span>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span style="margin-left: 155px; margin-top: 13px; width: 147px; height: 3px;"><img alt="" width="147" height="3"></span>
<span lang="EN-US"><span> </span>
0x02000000</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"><span> </span>
<span> </span>
0x01000000</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent"><span style="">每个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备都有一个</span>
<strong><span lang="EN-US">mtd_info</span>
</strong>
<span style="">结构,其中的</span>
<span lang="EN-US">priv</span>
<span style="">指针指向一个</span>
<strong><span lang="EN-US">map_info</span>
</strong>
<span style="">结构,</span>
<span lang="EN-US">map_info</span>
<span style="">结构中的</span>
<span lang="EN-US">fldrv_priv</span>
<span style="">指向一个</span>
<strong><span lang="EN-US">cfi_private</span>
</strong>
<span style="">结构,</span>
<span lang="EN-US">cfi_private</span>
<span style="">结构的</span>
<span lang="EN-US">cfiq</span>
<span style="">指针指向一个</span>
<strong><span lang="EN-US">cfi_ident</span>
</strong>
<span style="">结构,</span>
<span lang="EN-US">chips</span>
<span style="">指针指向一个</span>
<strong><span lang="EN-US">flchip</span>
</strong>
<span style="">结构的数组。其中</span>
<span lang="EN-US">mtd_info</span>
<span style="">、</span>
<span lang="EN-US">map_info</span>
<span style="">和</span>
<span lang="EN-US">cfi_private</span>
<span style="">结构用于描述</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备;因为组成</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的</span>
<span lang="EN-US">NOR</span>
<span style="">型</span>
<span lang="EN-US">Flash</span>
<span style="">相同,</span>
<span lang="EN-US">cfi_ident</span>
<span style="">结构用于描述</span>
<span lang="EN-US">Flash</span>
<span style="">芯片的信息;而</span>
<span lang="EN-US">flchip</span>
<span style="">结构用于描述每个</span>
<span lang="EN-US">Flash</span>
<span style="">芯片的专有信息(比如说起始地址)</span>
</p>
<p class="MsoNormalIndent"></p>
<h5>
<span style="font-size: medium;"><a name="_Toc7862215"><span lang="EN-US">NAND</span>
</a>
<span><span style="">和</span>
<span lang="EN-US">NOR</span>
</span>
<span><span style="">的比较</span>
</span>
</span>
</h5>
<p><span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">和</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">是现在市场上两种主要的非易失闪存技术。</span>
<span style="font-size: 10.5pt;" lang="EN-US">Intel</span>
<span style="">于</span>
<span style="font-size: 10.5pt;" lang="EN-US">1988</span>
<span style="">年首先开发出</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR flash</span>
<span style="">技术,彻底改变了原先由</span>
<span style="font-size: 10.5pt;" lang="EN-US">EPROM</span>
<span style="">和</span>
<span style="font-size: 10.5pt;" lang="EN-US">EEPROM</span>
<span style="">一统天下的局面。紧接着,</span>
<span style="font-size: 10.5pt;" lang="EN-US">1989</span>
<span style="">年,东芝公司发表了</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND flash</span>
<span style="">结构,强调降低每比特的成本,更高的性能,并且象磁盘一样可以通过接口轻松升级。但是经过了十多年之后,仍然有相当多的硬件工程师分不清</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">和</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">闪存。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  相</span>
<span style="font-size: 10.5pt;" lang="EN-US">“flash</span>
<span style="">存储器</span>
<span style="font-size: 10.5pt;" lang="EN-US">”</span>
<span style="">经常可以与相</span>
<span style="font-size: 10.5pt;" lang="EN-US">“NOR</span>
<span style="">存储器</span>
<span style="font-size: 10.5pt;" lang="EN-US">”</span>
<span style="">互换使用。许多业内人士也搞不清楚</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">闪存技术相对于</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">技术的优越之处,因为大多数情况下闪存只是用来存储少量的代码,这时</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">闪存更适合一些。而</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">则是高数据存储密度的理想解决方案。</span>
<span style="font-size: 10.5pt;" lang="EN-US"> <br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">的特点是芯片内执行</span>
<span style="font-size: 10.5pt;" lang="EN-US">(XIP, eXecute In Place)</span>
<span style="">,这样应用程序可以直接在</span>
<span style="font-size: 10.5pt;" lang="EN-US">flash</span>
<span style="">闪存内运行,不必再把代码读到系统</span>
<span style="font-size: 10.5pt;" lang="EN-US">RAM</span>
<span style="">中。</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">的传输效率很高,在</span>
<span style="font-size: 10.5pt;" lang="EN-US">1</span>
<span style="">~</span>
<span style="font-size: 10.5pt;" lang="EN-US">4MB</span>
<span style="">的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。应用</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">的困难在于</span>
<span style="font-size: 10.5pt;" lang="EN-US">flash</span>
<span style="">的管理和需要特殊的系统接口。</span>
</p>
<p><strong><span style="">性能比较</span>
</strong>
<strong></strong>
</p>
<p><span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">flash</span>
<span style="">闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何</span>
<span style="font-size: 10.5pt;" lang="EN-US">flash</span>
<span style="">器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件执行擦除操作是十分简单的,而</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">则要求在进行擦除前先要将目标块内所有的位都写为</span>
<span style="font-size: 10.5pt;" lang="EN-US">0</span>
<span style="">。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  由于擦除</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">器件时是以</span>
<span style="font-size: 10.5pt;" lang="EN-US">64</span>
<span style="">~</span>
<span style="font-size: 10.5pt;" lang="EN-US">128KB</span>
<span style="">的块进行的,执行一个写入</span>
<span style="font-size: 10.5pt;" lang="EN-US">/</span>
<span style="">擦除操作的时间为</span>
<span style="font-size: 10.5pt;" lang="EN-US">5s</span>
<span style="">,与此相反,擦除</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件是以</span>
<span style="font-size: 10.5pt;" lang="EN-US">8</span>
<span style="">~</span>
<span style="font-size: 10.5pt;" lang="EN-US">32KB</span>
<span style="">的块进行的,执行相同的操作最多只需要</span>
<span style="font-size: 10.5pt;" lang="EN-US">4ms</span>
<span style="">。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  执行擦除时块尺寸的不同进一步拉大了</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">和</span>
<span style="font-size: 10.5pt;" lang="EN-US">NADN</span>
<span style="">之间的性能差距,统计表明,对于给定的一套写入操作</span>
<span style="font-size: 10.5pt;" lang="EN-US">(</span>
<span style="">尤其是更新小文件时</span>
<span style="font-size: 10.5pt;" lang="EN-US">)</span>
<span style="">,更多的擦除操作必须在基于</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">的单元中进行。这样,当选择存储解决方案时,设计师必须权衡以下的各项因素。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">● NOR</span>
<span style="">的读速度比</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">稍快一些。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">● NAND</span>
<span style="">的写入速度比</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">快很多。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">● NAND</span>
<span style="">的</span>
<span style="font-size: 10.5pt;" lang="EN-US">4ms</span>
<span style="">擦除速度远比</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">的</span>
<span style="font-size: 10.5pt;" lang="EN-US">5s</span>
<span style="">快。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">● </span>
<span style="">大多数写入操作需要先进行擦除操作。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">● NAND</span>
<span style="">的擦除单元更小,相应的擦除电路更少。</span>
</p>
<p><span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<strong><span style="">接口差别</span>
</strong>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR flash</span>
<span style="">带有</span>
<span style="font-size: 10.5pt;" lang="EN-US">SRAM</span>
<span style="">接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件使用复杂的</span>
<span style="font-size: 10.5pt;" lang="EN-US">I/O</span>
<span style="">口来串行地存取数据,各个产品或厂商的方法可能各不相同。</span>
<span style="font-size: 10.5pt;" lang="EN-US">8</span>
<span style="">个引脚用来传送控制、地址和数据信息。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">读和写操作采用</span>
<span style="font-size: 10.5pt;" lang="EN-US">512</span>
<span style="">字节的块,这一点有点像硬盘管理此类操作,很自然地,基于</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">的存储器就可以取代硬盘或其他块设备。</span>
</p>
<p><span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<strong><span style="">容量和成本</span>
</strong>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND flash</span>
<span style="">的单元尺寸几乎是</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">器件的一半,由于生产过程更为简单,</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">结构可以在给定的模具尺寸内提供更高的容量,也就相应地降低了价格。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR flash</span>
<span style="">占据了容量为</span>
<span style="font-size: 10.5pt;" lang="EN-US">1</span>
<span style="">~</span>
<span style="font-size: 10.5pt;" lang="EN-US">16MB</span>
<span style="">闪存市场的大部分,而</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND flash</span>
<span style="">只是用在</span>
<span style="font-size: 10.5pt;" lang="EN-US">8</span>
<span style="">~</span>
<span style="font-size: 10.5pt;" lang="EN-US">128MB</span>
<span style="">的产品当中,这也说明</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">主要应用在代码存储介质中,</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">适合于数据存储,</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">在</span>
<span style="font-size: 10.5pt;" lang="EN-US">CompactFlash</span>
<span style="">、</span>
<span style="font-size: 10.5pt;" lang="EN-US">Secure Digital</span>
<span style="">、</span>
<span style="font-size: 10.5pt;" lang="EN-US">PC Cards</span>
<span style="">和</span>
<span style="font-size: 10.5pt;" lang="EN-US">MMC</span>
<span style="">存储卡市场上所占份额最大。</span>
</p>
<p><span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<strong><span style="">可靠性和耐用性</span>
</strong>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  采用</span>
<span style="font-size: 10.5pt;" lang="EN-US">flahs</span>
<span style="">介质时一个需要重点考虑的问题是可靠性。对于需要扩展</span>
<span style="font-size: 10.5pt;" lang="EN-US">MTBF</span>
<span style="">的系统来说,</span>
<span style="font-size: 10.5pt;" lang="EN-US">Flash</span>
<span style="">是非常合适的存储方案。可以从寿命</span>
<span style="font-size: 10.5pt;" lang="EN-US">(</span>
<span style="">耐用性</span>
<span style="font-size: 10.5pt;" lang="EN-US">)</span>
<span style="">、位交换和坏块处理三个方面来比较</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">和</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">的可靠性。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  <strong>寿命</strong>
</span>
<strong><span style="font-size: 10.5pt;" lang="EN-US">(</span>
</strong>
<strong><span style="">耐用性</span>
</strong>
<strong><span style="font-size: 10.5pt;" lang="EN-US">)</span>
</strong>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  在</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">闪存中每个块的最大擦写次数是一百万次,而</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">的擦写次数是十万次。</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">存储器除了具有</span>
<span style="font-size: 10.5pt;" lang="EN-US">10</span>
<span style="">比</span>
<span style="font-size: 10.5pt;" lang="EN-US">1</span>
<span style="">的块擦除周期优势,典型的</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">块尺寸要比</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">器件小</span>
<span style="font-size: 10.5pt;" lang="EN-US">8</span>
<span style="">倍,每个</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">存储器块在给定的时间内的删除次数要少一些。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  <strong>位交换</strong>
</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  所有</span>
<span style="font-size: 10.5pt;" lang="EN-US">flash</span>
<span style="">器件都受位交换现象的困扰。在某些情况下</span>
<span style="font-size: 10.5pt;" lang="EN-US">(</span>
<span style="">很少见,</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">发生的次数要比</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">多</span>
<span style="font-size: 10.5pt;" lang="EN-US">)</span>
<span style="">,一个比特位会发生反转或被报告反转了。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  一位的变化可能不很明显,但是如果发生在一个关键文件上,这个小小的故障可能导致系统停机。如果只是报告有问题,多读几次就可能解决了。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  当然,如果这个位真的改变了,就必须采用错误探测</span>
<span style="font-size: 10.5pt;" lang="EN-US">/</span>
<span style="">错误更正</span>
<span style="font-size: 10.5pt;" lang="EN-US">(EDC/ECC)</span>
<span style="">算法。位反转的问题更多见于</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">闪存,</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">的供应商建议使用</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">闪存的时候,同时使用</span>
<span style="font-size: 10.5pt;" lang="EN-US">EDC/ECC</span>
<span style="">算法。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  这个问题对于用</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">存储多媒体信息时倒不是致命的。当然,如果用本地存储设备来存储操作系统、配置文件或其他敏感信息时,必须使用</span>
<span style="font-size: 10.5pt;" lang="EN-US">EDC/ECC</span>
<span style="">系统以确保可靠性。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  <strong>坏块处理</strong>
</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件中的坏块是随机分布的。以前也曾有过消除坏块的努力,但发现成品率太低,代价太高,根本不划算。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  </span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件需要对介质进行初始化扫描以发现坏块,并将坏块标记为不可用。在已制成的器件中,如果通过可靠的方法不能进行这项处理,将导致高故障率。</span>
<span style="font-size: 10.5pt;" lang="EN-US"> <br><br></span>
<strong><span style="">易于使用</span>
</strong>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  可以非常直接地使用基于</span>
<span style="font-size: 10.5pt;" lang="EN-US">NOR</span>
<span style="">的闪存,可以像其他存储器那样连接,并可以在上面直接运行代码。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  由于需要</span>
<span style="font-size: 10.5pt;" lang="EN-US">I/O</span>
<span style="">接口,</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">要复杂得多。各种</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件的存取方法因厂家而异。</span>
<span style="font-size: 10.5pt;" lang="EN-US"><br></span>
<span style="">  在使用</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件时,必须先写入驱动程序,才能继续执行其他操作。向</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件写入信息需要相当的技巧,因为设计师绝不能向坏块写入,这就意味着在</span>
<span style="font-size: 10.5pt;" lang="EN-US">NAND</span>
<span style="">器件上自始至终都必须进行虚拟映射。</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"><br></span>
<strong><span style="">软件支持</span>
</strong>
<span lang="EN-US"><br></span>
<span style="">  当讨论软件支持的时候,应该区别基本的读</span>
<span lang="EN-US">/</span>
<span style="">写</span>
<span lang="EN-US">/</span>
<span style="">擦操作和高一级的用于磁盘仿真和闪存管理算法的软件,包括性能优化。</span>
<span lang="EN-US"><br></span>
<span style="">  在</span>
<span lang="EN-US">NOR</span>
<span style="">器件上运行代码不需要任何的软件支持,在</span>
<span lang="EN-US">NAND</span>
<span style="">器件上进行同样操作时,通常需要驱动程序,也就是内存技术驱动程序</span>
<span lang="EN-US">(MTD)</span>
<span style="">,</span>
<span lang="EN-US">NAND</span>
<span style="">和</span>
<span lang="EN-US">NOR</span>
<span style="">器件在进行写入和擦除操作时都需要</span>
<span lang="EN-US">MTD</span>
<span style="">。</span>
<span lang="EN-US"><br></span>
<span style="">  使用</span>
<span lang="EN-US">NOR</span>
<span style="">器件时所需要的</span>
<span lang="EN-US">MTD</span>
<span style="">要相对少一些,许多厂商都提供用于</span>
<span lang="EN-US">NOR</span>
<span style="">器件的更高级软件,这其中包括</span>
<span lang="EN-US">M-System</span>
<span style="">的</span>
<span lang="EN-US">TrueFFS</span>
<span style="">驱动,该驱动被</span>
<span lang="EN-US">Wind River System</span>
<span style="">、</span>
<span lang="EN-US">Microsoft</span>
<span style="">、</span>
<span lang="EN-US">QNX Software System</span>
<span style="">、</span>
<span lang="EN-US">Symbian</span>
<span style="">和</span>
<span lang="EN-US">Intel</span>
<span style="">等厂商所采用。</span>
<span lang="EN-US"><br></span>
<span style="">  驱动还用于对</span>
<span lang="EN-US">DiskOnChip</span>
<span style="">产品进行仿真和</span>
<span lang="EN-US">NAND</span>
<span style="">闪存的管理,包括纠错、坏块处理和损耗平衡。</span>
</p>
</div>
<p></p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span style="">下面具体介绍每个文件的内容和作用:</span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<h3>
<a name="_Toc7862217"><span style="">头文件分析</span>
</a>
</h3>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862218"><span lang="EN-US">mtd.h</span>
</a>
</h5>
<p class="MsoHeading7"><a name="_Toc7862219"><span lang="EN-US">MTD_CHAR_MAJOR</span>
</a>
</p>
<p class="MsoNormal"><span lang="EN-US">#define MTD_CHAR_MAJOR 90<span> </span>
MTD</span>
<span style="">字符设备的主设备号</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862220"><span lang="EN-US">MTD_BLOCK_MAJOR</span>
</a>
</p>
<p class="MsoNormal"><span lang="EN-US">#define MTD_BLOCK_MAJOR 31<span> </span>
MTD</span>
<span style="">块设备的主设备号</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862221"><span lang="EN-US">MAX_MTD_DEVICES</span>
</a>
</p>
<p class="MsoNormal"><span lang="EN-US">#define MAX_MTD_DEVICES 16<span> </span>
</span>
<span style="">最大</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备数</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862222"><span lang="EN-US">mtd_info</span>
</a>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">表示</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的结构,<span style="text-decoration: underline;">每个分区也被实现为一个</span>
</span>
<span style="text-decoration: underline;"><span lang="EN-US">mtd_info</span>
</span>
<span style="">,如果有两个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备,每个上有三个分区,在系统中就一共有</span>
<span lang="EN-US">6</span>
<span style="">个</span>
<span lang="EN-US">mtd_info</span>
<span style="">结构,这些</span>
<span lang="EN-US">mtd_info</span>
<span style="">的指针被存放在名为</span>
<span lang="EN-US">mtd_table</span>
<span style="">的数组里。</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct mtd_info {<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_char type;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">内存技术的类型</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t flags;</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">标志位</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t size;<span> </span>
// Total size of the MTD<span> </span>
</span>
<span lang="EN-US">mtd</span>
<span style="">设备的大小</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* "Major" erase size for the device. Na</span>
<span style="">飗</span>
<span style="color: blue;" lang="EN-US">e users may take this</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* to be the only erase size available, or may use the more detailed</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* information below if they desire</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t erasesize;</span>
<span style="">“主要的”</span>
<span lang="EN-US">erasesize</span>
<span style="">(同一个</span>
<span lang="EN-US">mtd</span>
<span style="">设备可能有数种不同的</span>
<span lang="EN-US">erasesize</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t oobblock;<span> </span>
// Size of OOB blocks (e.g. 512)<span> </span>
</span>
<span lang="EN-US">oob</span>
<span style="">块大小</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t oobsize;<span> </span>
// Amount of OOB data per block (e.g. 16)<span> </span>
</span>
<span lang="EN-US">oob</span>
<span style="">特别数据大小</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t ecctype;<span> </span>
</span>
<span lang="EN-US">ecc</span>
<span style="">类型</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t eccsize;<span> </span>
</span>
<span style="">自动</span>
<span lang="EN-US">ecc</span>
<span style="">可以工作的范围</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
// Kernel-only stuff starts here.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
char *name;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int index;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Data for variable erase regions. If numeraseregions is zero,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* it means that the whole device has erasesize as given above. </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
<span style="">不同的</span>
<span lang="EN-US">erasesize</span>
<span style="">的区域</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int numeraseregions;</span>
<span lang="EN-US"> </span>
<span style="">不同</span>
<span lang="EN-US">erasesize</span>
<span style="">的区域的数目(通常是</span>
<span lang="EN-US">1</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_erase_region_info *eraseregions; </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* This really shouldn't be here. It can go away in 2.5 */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t bank_size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct module *module;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*erase) (struct mtd_info *mtd, struct erase_info *instr);</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">此</span>
<span lang="EN-US">routine</span>
<span style="">用于将一个</span>
<span lang="EN-US">erase_info</span>
<span style="">加入</span>
<span lang="EN-US">erase queue</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* This stuff for eXecute-In-Place */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* We probably shouldn't allow XIP if the unpoint isn't a NULL */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*unpoint) (struct mtd_info *mtd, u_char * addr);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* iovec-based read/write methods. We need these especially for NAND flash,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
with its limited number of write cycles per erase.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
NB: The 'count' parameter is the number of _vectors_, each of </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
which contains an (ofs, len) tuple.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Sync */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*sync) (struct mtd_info *mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Chip-supported device locking */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Power Management functions */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*suspend) (struct mtd_info *mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*resume) (struct mtd_info *mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void *priv;<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">指向</span>
<span lang="EN-US">map_info</span>
<span style="">结构</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862223"><span lang="EN-US">mtd_info.type</span>
</a>
<span><span style="">的取值</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ABSENT<span> </span>
0</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_RAM<span> </span>
1</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ROM<span> </span>
2</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_NORFLASH<span> </span>
3</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_NANDFLASH<span> </span>
4</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_PEROM<span> </span>
5</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_OTHER<span> </span>
14</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_UNKNOWN<span> </span>
15</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862224"><span lang="EN-US">mtd_info.flags</span>
</a>
<span><span style="">的取值</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_CLEAR_BITS<span> </span>
1<span> </span>
// Bits can be cleared (flash)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_SET_BITS<span> </span>
2<span> </span>
// Bits can be set</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ERASEABLE<span> </span>
4<span> </span>
// Has an erase function</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_WRITEB_WRITEABLE<span> </span>
8<span> </span>
// Direct IO is possible</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_VOLATILE<span> </span>
16<span> </span>
// Set for RAMs</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_XIP<span> </span>
32<span> </span>
// eXecute-In-Place possible</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_OOB<span> </span>
64<span> </span>
// Out-of-band data (NAND flash)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ECC<span> </span>
128<span> </span>
// Device capable of automatic ECC</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">// Some common devices / combinations of capabilities</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_CAP_ROM<span> </span>
0</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_CAP_RAM<span> </span>
(MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_CAP_NORFLASH<span> </span>
(MTD_CLEAR_BITS|MTD_ERASEABLE)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_CAP_NANDFLASH<span> </span>
(MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_WRITEABLE<span> </span>
(MTD_CLEAR_BITS|MTD_SET_BITS)</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862225"><span lang="EN-US">mtd_info.ecctype</span>
</a>
<span><span style="">的取值</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ECC_NONE<span> </span>
0 <span> </span>
// No automatic ECC available</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ECC_RS_DiskOnChip<span> </span>
1<span> </span>
// Automatic ECC on DiskOnChip</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ECC_SW<span> </span>
2<span> </span>
// SW ECC for Toshiba &amp; Samsung devices</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862226"><span lang="EN-US">erase_info</span>
</a>
</p>
<p class="MsoNormal"><span style="">表示</span>
<span lang="EN-US">erase</span>
<span style="">动作的结构,由设备层调用</span>
<span lang="EN-US">mtd_info-&gt;erase</span>
<span style="">函数传递给原始设备层</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct erase_info {<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *mtd;<span> </span>
</span>
<span style="">被操作的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t addr;<span> </span>
</span>
<span style="">被操作的地址(</span>
<span lang="EN-US">byte</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t len;<span> </span>
</span>
<span style="">长度</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_long time;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_long retries;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int dev;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int cell;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*callback) (struct erase_info *self);<span> </span>
</span>
</p>
<p class="MsoNormal" style="margin-left: 105pt; text-indent: 21pt;"><span lang="EN-US">callback</span>
<span style="">函数指针,当</span>
<span lang="EN-US">erase</span>
<span style="">结束后该函数被调用</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_long priv;</span>
<span lang="EN-US"><span> </span>
user</span>
<span style="">模块提供的</span>
<span lang="EN-US">private</span>
<span style="">数据</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_char state;</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">当前状态</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct erase_info *next;<span> </span>
</span>
<span lang="EN-US">erase</span>
<span style="">队列中的下一个</span>
<span lang="EN-US">erase_info</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862227"><span lang="EN-US">erase_info.state</span>
</a>
<span><span style="">的取值</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ERASE_PENDING<span> </span>
<span> </span>
0x01</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ERASING<span> </span>
0x02</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ERASE_SUSPEND<span> </span>
0x04</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ERASE_DONE<span> </span>
<span> </span>
0x08</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTD_ERASE_FAILED<span> </span>
<span> </span>
0x10</span>
</p>
<p class="MsoNormal" style="margin-left: 42pt;"><span style="">驱动模块在</span>
<span lang="EN-US">erase</span>
<span style="">要求进入</span>
<span lang="EN-US">erase </span>
<span style="">队列时将</span>
<span lang="EN-US">state</span>
<span style="">设置为</span>
<span lang="EN-US">MTD_ERASE_PENDING</span>
<span style="">,当</span>
<span lang="EN-US">callback</span>
<span style="">被调用时设置为</span>
<span lang="EN-US">MTD_ERASE_DONE</span>
<span style="">或</span>
<span lang="EN-US">MTD_ERASE_FAILED</span>
<span style="">。</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862228"><span lang="EN-US">mtd_notifier</span>
</a>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">MTD</span>
<span style="">通知器(这个名字很古怪,但我找不到更好的词来翻译),加入</span>
<span lang="EN-US">/</span>
<span style="">删除</span>
<span lang="EN-US">MTD</span>
<span style="">设备和原始设备时调用的函数,在设备层,当</span>
<span lang="EN-US">MTD</span>
<span style="">字符设备或块设备注册时,<span style="text-decoration: underline;">如果定义了</span>
</span>
<span style="text-decoration: underline;"><span lang="EN-US">CONFIG_DEVFS_FS</span>
</span>
<span style="">,则会将一个</span>
<span lang="EN-US">mtd_notifier</span>
<span style="">加入</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备层的</span>
<span lang="EN-US">mtd_notifiers</span>
<span style="">链表,其中的函数会在两种情况下被调用</span>
<span lang="EN-US">,</span>
<span style="">一是加入</span>
<span lang="EN-US">/</span>
<span style="">删除新的</span>
<span lang="EN-US">MTD</span>
<span style="">字符</span>
<span lang="EN-US">/</span>
<span style="">块设备时,此时调用该</span>
<span lang="EN-US">MTD</span>
<span style="">字符</span>
<span lang="EN-US">/</span>
<span style="">块设备的</span>
<span lang="EN-US">notifier</span>
<span style="">对下层所有的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备操作一遍,二是加入</span>
<span lang="EN-US">/</span>
<span style="">删除新的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备时,此时调用所有的</span>
<span lang="EN-US">notifier</span>
<span style="">对该原始设备执行一遍。</span>
</p>
<p class="MsoNormal" style=""><span style="color: blue;" lang="EN-US">struct mtd_notifier {<span> </span>
</span>
</p>
<p class="MsoNormal" style=""><span style="color: blue;" lang="EN-US">void (*add)(struct mtd_info *mtd);<span> </span>
</span>
<span style="">加入时调用</span>
</p>
<p class="MsoNormal" style=""><span style="color: blue;" lang="EN-US">void (*remove)(struct mtd_info *mtd);<span> </span>
</span>
<span style="">删除时调用</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_notifier *next;<span> </span>
</span>
<span style="">指向</span>
<span lang="EN-US">mtd_notifiers</span>
<span style="">队列中的下一个</span>
<span lang="EN-US">mtd_notifier</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862229"><span lang="EN-US">get_mtd_device</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">获得一个</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">__get_mtd_device()</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">见</span>
<span lang="EN-US">__get_mtd_device()</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">要求的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
__get_mtd_device()</span>
</p>
<p class="MsoNormal"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">设备层函数,在设备层的</span>
<span lang="EN-US">open</span>
<span style="">函数中被调用以获得一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = __get_mtd_device(mtd, num);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret &amp;&amp; ret-&gt;module &amp;&amp; !try_inc_mod_count(ret-&gt;module))</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862230"><span lang="EN-US">put_mtd_device</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static inline void put_mtd_device(struct mtd_info *mtd)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">归还(</span>
<span lang="EN-US">put</span>
<span style="">)一个使用完的</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">该</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">设备层函数,通常在设备层的</span>
<span lang="EN-US">release</span>
<span style="">函数中调用。</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd-&gt;module)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
__MOD_DEC_USE_COUNT(mtd-&gt;module);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862231"><span lang="EN-US">partitions.h</span>
</a>
</h5>
<p class="MsoNormal"><span style="">此文件中的数据用来从</span>
<span lang="EN-US">/maps</span>
<span style="">子目录下的文件向原始设备层传递分区信息</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862232"><span lang="EN-US">mtd_partition</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* Partition definition structure:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* An array of struct partition is passed along with a MTD object to</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* add_mtd_partitions() to create them.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* For each partition, these fields are available:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* name: string that will be used to label the partition's MTD device.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* size: the partition size; if defined as MTDPART_SIZ_FULL, the partition </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* <span> </span>
will extend to the end of the master MTD device.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* offset: absolute starting position within the master MTD device; if </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* <span> </span>
defined as MTDPART_OFS_APPEND, the partition will start where the </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* <span> </span>
previous one ended.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* mask_flags: contains flags that have to be masked (removed) from the </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* <span> </span>
master MTD flag set for the corresponding MTD partition.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* <span> </span>
For example, to force a read-only partition, simply adding </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* <span> </span>
MTD_WRITEABLE to the mask_flags will do the trick.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* Note: writeable partitions require their size and offset be </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* erasesize aligned.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/ </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct mtd_partition {</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">描述</span>
<span lang="EN-US">mtd</span>
<span style="">设备分区的结构,在</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备层调用</span>
<span lang="EN-US">add_mtd_partions</span>
</p>
<p class="MsoNormal" style="margin-left: 84pt; text-indent: 21pt;"><span style="">时<strong>传递分区信息</strong>
用</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
char *name;<span> </span>
/* identifier string */<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t size;<span> </span>
/* partition size */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t offset;<span> </span>
/* offset within the master MTD space */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t mask_flags;<span> </span>
/* master MTD flags to mask out for this partition */</span>
<span style="">将被掩去的标</span>
</p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt;"><span style="">志位,(例如如果在分区时置</span>
<span lang="EN-US">mask_flags</span>
<span style="">为</span>
<span lang="EN-US">WRITEABLE</span>
<span style="">,则此分区为只读分区)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862233"><span lang="EN-US">MTDPART_OFS_APPEND</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTDPART_OFS_APPEND<span> </span>
(-1)</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">如果</span>
<span lang="EN-US">mtd_partition.offset</span>
<span style="">取此值,表示此分区</span>
</p>
<p class="MsoNormal" style="margin-left: 189pt; text-indent: 21pt;"><span style="">的</span>
<span lang="EN-US">offset</span>
<span style="">紧接上一个分区的结束</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862234"><span lang="EN-US">MTDPART_SIZ_FULL</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define MTDPART_SIZ_FULL<span> </span>
(0)</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">如果</span>
<span lang="EN-US">mtd_partion.size</span>
<span style="">取此值,表示此分区一</span>
</p>
<p class="MsoNormal" style="margin-left: 189pt; text-indent: 21pt;"><span style="">直到</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的最后结束</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862235"><span lang="EN-US">map.h</span>
</a>
</h5>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862236"><span lang="EN-US">map_info</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct map_info {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
char *name;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int buswidth; /* in octets */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8 (*read8)(struct map_info *, unsigned long);<span> </span>
</span>
<span lang="EN-US">Flash</span>
<span style="">的读写函数,(</span>
<span lang="EN-US">NOR</span>
<span style="">型</span>
<span lang="EN-US">Flash</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 (*read16)(struct map_info *, unsigned long);<span> </span>
</span>
<span style="">可以像内存一样进行读写),</span>
<span lang="EN-US">read8</span>
<span style="">、</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u32 (*read32)(struct map_info *, unsigned long);<span> </span>
</span>
<span lang="EN-US">read16</span>
<span style="">和</span>
<span lang="EN-US">read32</span>
<span style="">分别用于</span>
<span lang="EN-US">buswidth</span>
</p>
<p class="MsoNormal" style="margin-left: 231pt; text-indent: 21pt;"><span style="">为</span>
<span lang="EN-US">1</span>
<span style="">、</span>
<span lang="EN-US">2</span>
<span style="">、</span>
<span lang="EN-US">4</span>
<span style="">字节的情况(</span>
<span lang="EN-US">write</span>
<span style="">同理)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* If it returned a 'long' I'd call it readl.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* It doesn't.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* I won't.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* dwmw2 */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*write8)(struct map_info *, __u8, unsigned long);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*write16)(struct map_info *, __u16, unsigned long);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*write32)(struct map_info *, __u32, unsigned long);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*set_vpp)(struct map_info *, int);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* We put these two here rather than a single void *map_priv, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
because we want mappers to be able to have quickly-accessible</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
cache for the 'currently-mapped page' without the _extra_</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
redirection that would be necessary. If you need more than</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
two longs, turn the second into a pointer. dwmw2 */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long map_priv_1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long map_priv_2;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void *fldrv_priv;<span> </span>
</span>
<span style="">指向</span>
<span lang="EN-US">cfi_private</span>
<span style="">结构</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_chip_driver *fldrv;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862237"><span lang="EN-US">mtd_chip_driver</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct mtd_chip_driver {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *(*probe)(struct map_info *map);<span> </span>
</span>
<span style="">该芯片的</span>
<span lang="EN-US">probe</span>
<span style="">程序</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void (*destroy)(struct mtd_info *);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct module *module;<span> </span>
</span>
<span style="">模块</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
char *name;<span> </span>
</span>
<span style="">芯片名</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct list_head list;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US">MTD</span>
<span style="">芯片驱动器的结构</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862238"><span lang="EN-US">gen_probe.h</span>
</a>
</h5>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862239"><span lang="EN-US">chip_probe</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct chip_probe {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
char *name;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int (*probe_chip)(struct map_info *map, __u32 base,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
struct flchip *chips, struct cfi_private *cfi);<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span style="">通用探测程序的参数结构,此结构类型将<strong>作为参数</strong>
传进</span>
<span lang="EN-US">mtd_do_chip_probe()</span>
<span style="">中,</span>
<span lang="EN-US">mtd_do_chip_probe()</span>
<span style="">将间接调用其中的</span>
<span lang="EN-US">probe_chip</span>
<span style="">函数</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862240"><span lang="EN-US">cfi.h</span>
</a>
</h5>
<p class="MsoHeading7"><a name="_Toc7862241"><span lang="EN-US">cfi_private</span>
</a>
</p>
<p class="MsoNormal"><span lang="EN-US">CFI</span>
<span style="">私有信息</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct cfi_private {<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 cmdset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void *cmdset_priv;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int interleave;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">芯片交错数,</span>
<span lang="EN-US">interleave</span>
<span style="">片芯片交织连接成一个芯片</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int device_type;<span> </span>
</span>
<span style="">每一片</span>
<span lang="EN-US">Flash</span>
<span style="">的类型(</span>
<span lang="EN-US">1</span>
<span style="">:</span>
<span lang="EN-US">8bits</span>
<span style="">,</span>
<span lang="EN-US">2</span>
<span style="">:</span>
<span lang="EN-US">16bits</span>
<span style="">,</span>
<span lang="EN-US">4</span>
<span style="">:</span>
<span lang="EN-US">32bits</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int cfi_mode;<span> </span>
/* Are we a JEDEC device pretending to be CFI? */<span> </span>
</span>
<span lang="EN-US">CFI</span>
<span style="">的模式</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int addr_unlock1;<span> </span>
</span>
<span style="">命令地址,所谓“</span>
<span lang="EN-US">unlock</span>
<span style="">”是指无论</span>
<span lang="EN-US">Flash</span>
<span style="">处于读模式或写模式,都</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int addr_unlock2;<span> </span>
</span>
<span style="">可向该地址写命令</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int fast_prog;<span> </span>
</span>
<span style="">允许</span>
<span lang="EN-US">Fast Program</span>
<span style="">模式</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *(*cmdset_setup)(struct map_info *);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct cfi_ident *cfiq; /* For now only one. We insist that all devs<span> </span>
</span>
<span style="">每个芯片的信息</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
must be of the same type. */<span> </span>
</span>
<span style="">(所有芯片是同类型的)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int mfr, id;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int numchips;<span> </span>
</span>
<span lang="EN-US"><span> </span>
Flash</span>
<span style="">芯片个数(</span>
<span lang="EN-US">N interleave</span>
<span style="">算一块芯片)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long chipshift; /* Because they're of the same type */</span>
</p>
<p class="MsoNormal" style="margin-left: 168pt; text-indent: 21pt;"><span style="">每块芯片大小</span>
<span lang="EN-US">*interleave=2</span>
<span style="">的</span>
<span lang="EN-US">chipshift</span>
<span style="">次方</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
const char *im_name;<span> </span>
/* inter_module name for cmdset_setup */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct flchip chips[0];<span> </span>
/* per-chip data structure for each chip */</span>
<span style="">每一块芯片的信息</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862242"><span lang="EN-US">cfi_private.cfi_mode</span>
</a>
<span><span style="">的取值</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define CFI_MODE_CFI<span> </span>
0<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">真的是</span>
<span lang="EN-US">CFI</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define CFI_MODE_JEDEC<span> </span>
1<span> </span>
</span>
<span lang="EN-US">JEDEC</span>
<span style="">仿真</span>
<span lang="EN-US">CFI</span>
</p>
<p class="MsoSalutation"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862243"><span lang="EN-US">cfi_ident</span>
</a>
</p>
<p class="MsoNormal"><span lang="EN-US">CFI</span>
<span style="">接口芯片的查询结构,从芯片起始地址</span>
<span lang="EN-US">+0x10</span>
<span style="">开始的</span>
<span lang="EN-US">0x2C</span>
<span style="">个字节</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/* Basic Query Structure */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct cfi_ident {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
qry[3];<span> </span>
</span>
<span style="">“</span>
<span lang="EN-US">QRY</span>
<span style="">”</span>
<span lang="EN-US"><span> </span>
0x10,0x11,0x12</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 P_ID;<span> </span>
</span>
<span style="">制造商</span>
<span lang="EN-US">ID<span> </span>
Primary ID<span> </span>
0x13,0x14</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 P_ADR;<span> </span>
<span> </span>
</span>
<span lang="EN-US">Primary Address <span> </span>
0x15,0x16</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 A_ID;<span> </span>
</span>
<span lang="EN-US">Alternate ID <span> </span>
0x17,0x18<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 A_ADR;<span> </span>
</span>
<span lang="EN-US">Alternate Address<span> </span>
0x19,0x1A</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
VccMin;<span> </span>
</span>
<span style="">逻辑供电</span>
<span lang="EN-US">Vcc</span>
<span style="">最小电压</span>
<span lang="EN-US"><span> </span>
0x1B</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
VccMax;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">逻辑供电</span>
<span lang="EN-US">Vcc</span>
<span style="">最大电压</span>
<span lang="EN-US"><span> </span>
0x1C</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
VppMin;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">编程</span>
<span lang="EN-US">/</span>
<span style="">擦除供电</span>
<span lang="EN-US">Vpp</span>
<span style="">最小电压</span>
<span lang="EN-US"><span> </span>
0x1D</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
VppMax;<span> </span>
</span>
<span style="">编程</span>
<span lang="EN-US">/</span>
<span style="">擦除供电</span>
<span lang="EN-US">Vpp</span>
<span style="">最大电压</span>
<span lang="EN-US"><span> </span>
0x1E</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
WordWriteTimeoutTyp;<span> </span>
</span>
<span style="">典型单字节</span>
<span lang="EN-US">/</span>
<span style="">字写周期定时时间</span>
<span lang="EN-US"><span> </span>
0x1F</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
BufWriteTimeoutTyp;</span>
<span lang="EN-US"> <span> </span>
0x20</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
BlockEraseTimeoutTyp;<span> </span>
</span>
<span style="">典型单块擦除定时时间</span>
<span lang="EN-US"><span> </span>
0x21</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
ChipEraseTimeoutTyp;<span> </span>
</span>
<span style="">典型整片擦除定时时间</span>
<span lang="EN-US"><span> </span>
0x22</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
WordWriteTimeoutMax;</span>
<span lang="EN-US"> </span>
<span style="">单字节</span>
<span lang="EN-US">/</span>
<span style="">字写周期最大定时时间</span>
<span lang="EN-US"><span> </span>
0x23</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
BufWriteTimeoutMax;<span> </span>
</span>
<span lang="EN-US">0x24</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
BlockEraseTimeoutMax;</span>
<span lang="EN-US"> </span>
<span style="">单块擦除最大定时时间</span>
<span lang="EN-US"><span> </span>
0x25</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
ChipEraseTimeoutMax;</span>
<span lang="EN-US"> </span>
<span style="">整片擦除最大定时时间</span>
<span lang="EN-US"><span> </span>
0x26</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
DevSize;</span>
<span lang="EN-US"> <span> </span>
</span>
<span style="">器件体积</span>
<span lang="EN-US"><span> </span>
0x27</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 InterfaceDesc;<span> </span>
</span>
<span lang="EN-US">Flash</span>
<span style="">器件接口识别码</span>
<span lang="EN-US">ID<span> </span>
0x28,0x29</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u16 MaxBufWriteSize;<span> </span>
</span>
<span lang="EN-US">0x2A,0x2B</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u8<span> </span>
NumEraseRegions;</span>
<span lang="EN-US"> <span> </span>
</span>
<span style="">器件可擦除块区域个数</span>
<span lang="EN-US"><span> </span>
0x2C</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__u32 EraseRegionInfo[0]; /* Not host ordered */<span> </span>
</span>
<span style="">擦除块区域信息:</span>
<span lang="EN-US"><span> </span>
0x2D</span>
<span style="">—</span>
<span lang="EN-US">0x3C </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">} __attribute__((packed));`<span> </span>
</span>
<span lang="EN-US">bit15-0=y</span>
<span style="">该擦除块区域内含同样体积擦除块的个数</span>
<span lang="EN-US">=y+1 </span>
</p>
<p class="MsoNormal" style="margin-left: 126pt; text-indent: 21pt;"><span lang="EN-US">bit31-16=z</span>
<span style="">该区域每个擦除块体积</span>
<span lang="EN-US">=z x 256</span>
<span style="">字节</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862244"><span lang="EN-US">cfi_ident.P_ID</span>
</a>
<span><span style="">的取值</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_NONE 0</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_INTEL_EXT 1</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_AMD_STD 2</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_INTEL_STD 3</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_AMD_EXT 4</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_MITSUBISHI_STD 256</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_MITSUBISHI_EXT 257</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define P_ID_RESERVED 65535</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862245"><span lang="EN-US">flashchip.h</span>
</a>
</h5>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862246"><span lang="EN-US">flchip</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct flchip {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long start; /* Offset within the map */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
//<span> </span>
unsigned long len;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">假设所有的</span>
<span lang="EN-US">Flash chip</span>
<span style="">都是相同的,所以没有定义</span>
<span lang="EN-US">len</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* We omit len for now, because when we group them together</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
we insist that they're all of the same size, and the chip size</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
is held in the next level up. If we get more versatile later,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
it'll make it a damn sight harder to find which chip we want from</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
a given offset, and we'll want to add the per-chip length field</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
back in.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
flstate_t state;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
flstate_t oldstate;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spinlock_t *mutex;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
wait_queue_head_t wq; /* Wait on here when we're waiting for the chip</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
to be ready */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int word_write_time;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int buffer_write_time;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int erase_time;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<h3>
<a name="_Toc7862247"><span lang="EN-US">/drivers/mtd/</span>
</a>
<span><span style="">子目录</span>
</span>
</h3>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormalIndent" style="text-indent: 0cm;"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862248"><span lang="EN-US">mtdcore.c</span>
</a>
</h5>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">本文件主要实现了</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备层的数据结构</span>
<strong><span lang="EN-US">mtd_table</span>
</strong>
<span style="">和对其的操作函数,主要包括</span>
<strong><span lang="EN-US">add_mtd_device()</span>
</strong>
<span style="">(加入</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备)、</span>
<strong><span lang="EN-US">del_mtd_device()</span>
</strong>
<span style="">(删除</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备)</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862249"><span lang="EN-US">mtd_table</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">static struct mtd_info *mtd_table[MAX_MTD_DEVICES];</span>
</p>
<p class="MsoNormal" style="margin-left: 63pt;"><span style="">标示</span>
<span lang="EN-US">MTD</span>
<span style="">设备的数组,最多可以有</span>
<span lang="EN-US">MAX_MTD_DEVICES</span>
<span style="">个设备(每一个</span>
<span lang="EN-US">MTD</span>
<span style="">分区也算一个</span>
<span lang="EN-US">MTD</span>
<span style="">设备)</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862250"><span lang="EN-US">mtd_notifiers</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">static struct mtd_notifier *mtd_notifiers = NULL;</span>
</p>
<p class="MsoNormal" style="margin-left: 63pt;"><span style="">标示</span>
<span lang="EN-US">mtd_notifier</span>
<span style="">队列的指针</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoSalutation"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862251"><span lang="EN-US">add_mtd_device</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="color: blue;" lang="EN-US">int add_mtd_device(struct mtd_info *mtd)</span>
</p>
<p class="MsoNormal"><strong><span style="">注释</span>
<span lang="EN-US">:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/**</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
add_mtd_device - register an MTD device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
@mtd: pointer to new MTD device info structure</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
Add a device to the list of MTD devices present in the system, and</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
notify each currently active MTD 'user' of its arrival. Returns</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
zero on success or 1 on failure, which currently will only happen</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoNormal"><strong><span style="">功能:</span>
</strong>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">加入一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备。</span>
</p>
<p class="MsoNormal"><strong><span style="">参数:</span>
</strong>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">mtd</span>
<span style="">:被加入的原始设备</span>
</p>
<p class="MsoNormal"><strong><span style="">返回:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd_table</span>
<span style="">已满:返回</span>
<span lang="EN-US">1</span>
</p>
<p class="MsoNormal"><strong><span style="">说明:</span>
</strong>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">1.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">加入此原始设备的</span>
<span lang="EN-US">mtd_info</span>
<span style="">到</span>
<span lang="EN-US">mtd_table</span>
<span style="">中,</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">2.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span lang="EN-US">notify</span>
<span style="">所有的</span>
<span lang="EN-US">MTD</span>
<span style="">设备一个</span>
<span lang="EN-US">mtd</span>
<span style="">被加入(调用所有的</span>
<span lang="EN-US">notifier-&gt;add(mtd)</span>
<span style="">)。</span>
</p>
<p class="MsoNormal"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><strong><span lang="EN-US"><span> </span>
</span>
</strong>
<span lang="EN-US">notifers-&gt;add(mtd)</span>
</p>
<p class="MsoNormal"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
Flash</span>
<span style="">相关文件(</span>
<span lang="EN-US">your-flash.c</span>
<span style="">)初始化时(</span>
<span lang="EN-US">maps</span>
<span style="">子目录下的文件中的</span>
<span lang="EN-US">init_xxx</span>
<span style="">函数)</span>
</p>
<p class="MsoNormal"><strong><span style="">源代码:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i&lt; MAX_MTD_DEVICES; i++)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!mtd_table[i])<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">找到</span>
<span lang="EN-US">mtd_table</span>
<span style="">中的空项</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_notifier *not=mtd_notifiers;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_table[i] = mtd;<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">将其指向新加入的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd-&gt;index = i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(0, "mtd: Giving out device %d to %s/n",i, mtd-&gt;name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
while (not)<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">如果有</span>
<span lang="EN-US">notifier</span>
<span style="">,调用所有的</span>
<span lang="EN-US">notifier</span>
<span style="">对新加</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">入的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备操作一遍</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
(*(not-&gt;add))(mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
not = not-&gt;next;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_INC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}<strong><span> </span>
</strong>
</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862252"><span lang="EN-US">del_mtd_device</span>
</a>
</p>
<p class="MsoNormal"><strong><span style="">格式:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int del_mtd_device (struct mtd_info *mtd)</span>
</p>
<p class="MsoNormal"><strong><span style="">注释:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/**</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
del_mtd_device - unregister an MTD device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
@mtd: pointer to MTD device info structure</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
Remove a device from the list of MTD devices present in the system,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
and notify each currently active MTD 'user' of its departure.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
Returns zero on success or 1 on failure, which currently will happen</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
if the requested device does not appear to be present in the list.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><strong><span style="">功能:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">删除一个</span>
<span lang="EN-US">mtd</span>
<span style="">设备。</span>
</p>
<p class="MsoNormal"><strong><span style="">说明:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">从</span>
<span lang="EN-US">mtd_table</span>
<span style="">中删除此设备的</span>
<span lang="EN-US">mtd_info</span>
<span style="">,通知所有的</span>
<span lang="EN-US">MTD</span>
<span style="">设备(调用所有的</span>
<span lang="EN-US">notifier.remove</span>
<span style="">(</span>
<span lang="EN-US">mtd</span>
<span style="">))</span>
</p>
<p class="MsoNormal"><strong><span style="">参数:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd</span>
<span style="">:描述此设备的</span>
<span lang="EN-US">mtd_info</span>
</p>
<p class="MsoNormal"><strong><span style="">返回:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">此设备不在</span>
<span lang="EN-US">mtd_table</span>
<span style="">中:返回</span>
<span lang="EN-US">1</span>
</p>
<p class="MsoNormal"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
notifiers-&gt;remove(mtd)</span>
</p>
<p class="MsoNormal"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
Flash</span>
<span style="">相关文件(</span>
<span lang="EN-US">your-flash.c</span>
<span style="">)清除设备时(</span>
<span lang="EN-US">drivers/mtd/maps</span>
<span style="">子目录下的文件中的</span>
<span lang="EN-US">cleanupt_xxx</span>
<span style="">函数)</span>
</p>
<p class="MsoNormal"><strong><span style="">源代码:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_notifier *not=mtd_notifiers;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i &lt; MAX_MTD_DEVICES; i++)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd_table[i] == mtd)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
while (not)<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">如果有</span>
<span lang="EN-US">notifier</span>
<span style="">,调用所有的</span>
<span lang="EN-US">notifier</span>
<span style="">对</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">被删除的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备操作一遍</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
(*(not-&gt;remove))(mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
not = not-&gt;next;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_table[i] = NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up (&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_DEC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862253"><span lang="EN-US">register_mtd_user</span>
</a>
</p>
<p class="MsoNormal"><strong><span style="">格式:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
void register_mtd_user (struct mtd_notifier *new)</span>
</p>
<p class="MsoNormal"><strong><span style="">注释:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/**</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
register_mtd_user - register a 'user' of MTD devices.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
@new: pointer to notifier info structure</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
Registers a pair of callbacks function to be called upon addition</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
or removal of MTD devices. Causes the 'add' callback to be immediately</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
invoked for each MTD device currently present in the system.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><strong><span style="">功能:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">加入一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的使用者(即</span>
<span lang="EN-US">MTD</span>
<span style="">设备,</span>
<span lang="EN-US">MTD</span>
<span style="">块设备或字符设备)。</span>
</p>
<p class="MsoNormal"><strong><span style="">说明:</span>
</strong>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">1.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">将新的</span>
<span lang="EN-US">mtd</span>
<span style="">通知器</span>
<span lang="EN-US">new</span>
<span style="">加入</span>
<span lang="EN-US">notifer</span>
<span style="">队列中,</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">2.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">增加模块的</span>
<span lang="EN-US">use count</span>
<span style="">,</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">3.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">对所有已有的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备调用</span>
<span lang="EN-US">new-&gt;add()</span>
<span style="">。</span>
</p>
<p class="MsoNormal"><strong><span style="">参数:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
new</span>
<span style="">:新</span>
<span lang="EN-US">MTD</span>
<span style="">设备的</span>
<span lang="EN-US">mtd_notifier</span>
</p>
<p class="MsoNormal"><strong><span style="">返回:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoNormal"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
new-&gt;add()</span>
</p>
<p class="MsoNormal"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">(如果定义了</span>
<span lang="EN-US">CONFIG_DEVFS</span>
<span style="">)</span>
<span lang="EN-US">MTD</span>
<span style="">设备级的初始化(</span>
<span lang="EN-US">mtdblock.c</span>
<span style="">、</span>
<span lang="EN-US">mtdchar.c</span>
<span style="">、</span>
<span lang="EN-US">ftl.c</span>
<span style="">中的</span>
<span lang="EN-US">init_xxx</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><strong><span style="">源代码:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
new-&gt;next = mtd_notifiers;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_notifiers = new;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
<span> </span>
MOD_INC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i&lt; MAX_MTD_DEVICES; i++)<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">对所有的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备操作一遍</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd_table[i])</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
new-&gt;add(mtd_table[i]);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862254"><span lang="EN-US">unregister_mtd_user</span>
</a>
</p>
<p class="MsoNormal"><strong><span style="">格式:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int unregister_mtd_user (struct mtd_notifier *old)</span>
</p>
<p class="MsoNormal"><strong><span style="">注释:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/**</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
unregister_mtd_user - unregister a 'user' of MTD devices.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
@new: pointer to notifier info structure</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
Removes a callback function pair from the list of 'users' to be</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
notified upon addition or removal of MTD devices. Causes the</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
'remove' callback to be immediately invoked for each MTD device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
currently present in the system.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoNormal"><strong><span style="">功能:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">删除一个</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoNormal"><strong><span style="">说明:</span>
</strong>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">1.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">将被删除</span>
<span lang="EN-US">MTD</span>
<span style="">设备的通知器</span>
<span lang="EN-US">old</span>
<span style="">从</span>
<span lang="EN-US">notifer</span>
<span style="">队列中删除</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">2.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">减模块的</span>
<span lang="EN-US">use count</span>
<span style="">,</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">3.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">对所有已有的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备调用</span>
<span lang="EN-US">old-&gt;remove()</span>
<span style="">。</span>
</p>
<p class="MsoNormal"><strong><span style="">参数:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
old</span>
<span style="">:被删除</span>
<span lang="EN-US">MTD</span>
<span style="">设备的</span>
<span lang="EN-US">mtd_notifier</span>
</p>
<p class="MsoNormal"><strong><span style="">返回:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
notifiers</span>
<span style="">队列中无此设备的</span>
<span lang="EN-US">notifier</span>
<span style="">:返回</span>
<span lang="EN-US">1</span>
</p>
<p class="MsoNormal"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
old-&gt;remove()</span>
</p>
<p class="MsoNormal"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">(如果定义了</span>
<span lang="EN-US">CONFIG_DEVFS</span>
<span style="">)</span>
<span lang="EN-US">MTD</span>
<span style="">设备级的清除(</span>
<span lang="EN-US">mtdblock.c</span>
<span style="">、</span>
<span lang="EN-US">mtdchar.c</span>
<span style="">、</span>
<span lang="EN-US">ftl.c</span>
<span style="">中的</span>
<span lang="EN-US">cleanup_xxx</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><strong><span style="">源代码:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_notifier **prev = &amp;mtd_notifiers;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_notifier *cur;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
while ((cur = *prev)) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (cur == old) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
*prev = cur-&gt;next;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_DEC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i&lt; MAX_MTD_DEVICES; i++)<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">对所有的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备调用一遍</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd_table[i])<span> </span>
</span>
<span lang="EN-US">//remove</span>
<span style="">函数</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
old-&gt;remove(mtd_table[i]);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
prev = &amp;cur-&gt;next;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862255"><span lang="EN-US">__get_mtd_device</span>
</a>
</p>
<p class="MsoNormal"><strong><span style="">格式:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num)</span>
</p>
<p class="MsoNormal"><strong><span style="">注释:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/**</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
__get_mtd_device - obtain a validated handle for an MTD device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
@mtd: last known address of the required MTD device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
@num: internal device number of the required MTD device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
Given a number and NULL address, return the num'th entry in the device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
table, if any.<span> </span>
Given an address and num == -1, search the device table</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
for a device with that address and return if it's still present. Given</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
both, return the num'th driver only if its address matches. Return NULL</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
if not. get_mtd_device() increases the use count, but</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*<span> </span>
__get_mtd_device() doesn't - you should generally use get_mtd_device().</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoNormal"><strong><span style="">功能:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">返回指定的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的</span>
<span lang="EN-US">handler</span>
</p>
<p class="MsoNormal"><strong><span style="">说明:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
num==-1&amp;mtd!=NULL</span>
<span style="">:返回与</span>
<span lang="EN-US">mtd</span>
<span style="">地址相同的设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
0&lt;num&lt;MAX_MTD_DEVICES&amp;mtd==NULL</span>
<span style="">:返回</span>
<span lang="EN-US">mtd_table</span>
<span style="">中的第</span>
<span lang="EN-US">num</span>
<span style="">个</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
0&lt;num&lt;MAX_MTD_DEVICES&amp;mtd!=NULL</span>
<span style="">:如果</span>
<span lang="EN-US">mtd_table</span>
<span style="">中第</span>
<span lang="EN-US">num</span>
<span style="">个设备为</span>
<span lang="EN-US">mtd</span>
<span style="">,</span>
</p>
<p class="MsoNormal" style="margin-left: 210pt; text-indent: 21pt;"><span style="">返回</span>
<span lang="EN-US">mtd</span>
<span style="">;否则返回空。</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">其余情况:返回</span>
<span lang="EN-US">NULL</span>
<span style="">。</span>
</p>
<p class="MsoNormal"><strong><span style="">参数:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd</span>
<span style="">:指定</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的指针</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
num</span>
<span style="">:见说明</span>
</p>
<p class="MsoNormal"><strong><span style="">返回:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">见说明</span>
</p>
<p class="MsoNormal"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoNormal"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
get_mtd_device()</span>
</p>
<p class="MsoNormal"><strong><span style="">源代码:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *ret = NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (num == -1) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i&lt; MAX_MTD_DEVICES; i++)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd_table[i] == mtd)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = mtd_table[i];</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
} else if (num &lt; MAX_MTD_DEVICES) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = mtd_table[num];</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd &amp;&amp; mtd != ret)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtd_table_mutex);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862256"><span lang="EN-US">mtdpart.c</span>
</a>
</h5>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
MTD</span>
<span style="">原始设备层分区的实现,</span>
<span lang="EN-US">mtd_part</span>
<span style="">结构是用于描述分区的,由</span>
<strong><span lang="EN-US">mtd_partitons</span>
</strong>
<span style="">将</span>
<span lang="EN-US">mtd_part</span>
<span style="">中的</span>
<span lang="EN-US">list</span>
<span style="">成员链成一个链表。每个</span>
<span lang="EN-US">mtd_part</span>
<span style="">结构中的</span>
<span lang="EN-US">mtd_info</span>
<span style="">结构用于描述本分区,被加入</span>
<span lang="EN-US">mtd_table</span>
<span style="">中,其中大部分成员由其主分区</span>
<span lang="EN-US">mtd_part-&gt;master</span>
<span style="">决定,各种函数也指向主分区的相应函数。而主分区(其大小涵盖所有分区)则不作为一个</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备加入</span>
<span lang="EN-US">mtd_table</span>
<span style="">。</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">本文件向外提供的</span>
<strong><span lang="EN-US">add_mtd_partitions()</span>
</strong>
<span style="">和</span>
<strong><span lang="EN-US">del_mtd_partitions()</span>
</strong>
<span style="">根据参数</span>
<span lang="EN-US">map_info</span>
<span style="">结构将所有的分区加入</span>
<span lang="EN-US">mtd_table</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdpart.c</span>
<span style="">中还实现了</span>
<span lang="EN-US">part_read</span>
<span style="">、</span>
<span lang="EN-US">part_write</span>
<span style="">等函数,这些函数注册在每个分区中,指向主分区的</span>
<span lang="EN-US">read</span>
<span style="">、</span>
<span lang="EN-US">write</span>
<span style="">函数,之所以这样做而不直接将主分区的</span>
<span lang="EN-US">read</span>
<span style="">、</span>
<span lang="EN-US">write</span>
<span style="">函数连接到每个分区中的原因<span style="text-decoration: underline;">是因为函数中的参数</span>
</span>
<span style="text-decoration: underline;"><span lang="EN-US">mtd_info</span>
</span>
<span style="text-decoration: underline;"><span style="">会被调用者置为函数所属的</span>
<span lang="EN-US">mtd_info</span>
</span>
<span style="">,即</span>
<span lang="EN-US">mtd-&gt;read(mtd…)</span>
<span style="">,而参数</span>
<span lang="EN-US">mtd_info</span>
<span style="">其实应该指向主分区。</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862257"><span lang="EN-US">mtd_partitions</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/* Our partition linked list */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">static LIST_HEAD(mtd_partitions);<span> </span>
<span> </span>
</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备分区的链表</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862258"><span lang="EN-US">mtd_part</span>
</a>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">描述分区的结构</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/* Our partition node structure */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct mtd_part {</span>
<span lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
<span style="color: blue;">struct mtd_info mtd;<span> </span>
</span>
</span>
<span style="">分区的信息(大部分由其</span>
<span lang="EN-US">master</span>
<span style="">决定)</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
<span style="color: blue;">struct mtd_info *master;<span> </span>
</span>
</span>
<span style="">该分区的主分区</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
<span style="color: blue;">u_int32_t offset;<span> </span>
</span>
<span> </span>
</span>
<span style="">该分区的偏移地址</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
<span style="color: blue;">int index;<span> </span>
</span>
<span> </span>
</span>
<span style="">分区号</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct list_head list;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862259"><span lang="EN-US">PART(x)</span>
</a>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* Given a pointer to the MTD object in the mtd_part structure, we can retrieve</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* the pointer to that structure with this macro.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#define PART(x)<span> </span>
((struct mtd_part *)(x))<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">将</span>
<span lang="EN-US">mtd_info</span>
<span style="">结构转换为</span>
<span lang="EN-US">mtd_part</span>
<span style="">结构</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862260"><span lang="EN-US">add_mtd_partitions</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int add_mtd_partitions(struct mtd_info *master, struct mtd_partition *parts, int nbparts)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* This function, given a master MTD object and a partition table, creates</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* and registers slave MTD objects which are bound to the master according to</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* the partition definitions.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* (Q: should we register the master MTD object as well?)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">将</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备分区</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">打印信息(型如“</span>
<span lang="EN-US">Creating 3 MTD partitions on "Your Flash map</span>
<span style="">”),</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">对每一个新建分区</span>
<span lang="EN-US">{</span>
</p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt;"><span style="">建立一个新的</span>
<span lang="EN-US">mtd_part</span>
<span style="">结构,并将其加入</span>
<span lang="EN-US">mtd_partitions</span>
<span style="">中,</span>
</p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt;"><span style="">根据</span>
<span lang="EN-US">master</span>
<span style="">设置</span>
<span lang="EN-US">mtd_part.mtd_info</span>
<span style="">的成员,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">打印信息(型如“</span>
<span lang="EN-US">0x00020000-0x00800000 : "Your Kernel"</span>
<span style="">”),</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">进行安全性检查,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">根据</span>
<span lang="EN-US">master-&gt;numeraseregions</span>
<span style="">处理多</span>
<span lang="EN-US">erasesize</span>
<span style="">区域的事务,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">add_mtd_device</span>
<span style="">将此分区作为</span>
<span lang="EN-US">MTD</span>
<span style="">设备加入</span>
<span lang="EN-US">mtd_table</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
master</span>
<span style="">:指定的</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
parts</span>
<span style="">:关于分区信息的指针</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
nbparts</span>
<span style="">:分区的数目</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">分配</span>
<span lang="EN-US">mtd_part</span>
<span style="">时内存不足:返回</span>
<span lang="EN-US">-ENOMEM</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
add_mtd_device()</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
del_mtd_partitions()</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
flash</span>
<span style="">相关的初始化函数中(</span>
<span lang="EN-US">maps</span>
<span style="">子目录下的文件的函数</span>
<span lang="EN-US">init_xxx</span>
<span style="">中)</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_part *slave;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
u_int32_t cur_offset = 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk (KERN_NOTICE "Creating %d MTD partitions on /"%s/":/n", nbparts, master-&gt;name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i = 0; i &lt; nbparts; i++) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* allocate the partition structure */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave = kmalloc (sizeof(*slave), GFP_KERNEL);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!slave) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk ("memory allocation error while creating partitions for /"%s/"/n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
master-&gt;name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
del_mtd_partitions(master);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -ENOMEM;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
memset(slave, 0, sizeof(*slave));</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
list_add(&amp;slave-&gt;list, &amp;mtd_partitions);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* set up the MTD object for this partition */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.type = master-&gt;type;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.flags = master-&gt;flags &amp; ~parts[i].mask_flags;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.size = parts[i].size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.oobblock = master-&gt;oobblock;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.oobsize = master-&gt;oobsize;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.ecctype = master-&gt;ecctype;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.eccsize = master-&gt;eccsize;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.name = parts[i].name;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.bank_size = master-&gt;bank_size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.module = master-&gt;module;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.read = part_read;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.write = part_write;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (master-&gt;sync)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.sync = part_sync;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!i &amp;&amp; master-&gt;suspend &amp;&amp; master-&gt;resume) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.suspend = part_suspend;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.resume = part_resume;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (master-&gt;writev)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.writev = part_writev;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (master-&gt;readv)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.readv = part_readv;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (master-&gt;lock)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.lock = part_lock;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (master-&gt;unlock)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.unlock = part_unlock;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.erase = part_erase;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;master = master;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;offset = parts[i].offset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;index = i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (slave-&gt;offset == MTDPART_OFS_APPEND)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;offset = cur_offset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (slave-&gt;mtd.size == MTDPART_SIZ_FULL)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.size = master-&gt;size - slave-&gt;offset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
cur_offset = slave-&gt;offset + slave-&gt;mtd.size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk (KERN_NOTICE "0x%08x-0x%08x : /"%s/"/n", slave-&gt;offset, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;offset + slave-&gt;mtd.size, slave-&gt;mtd.name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* let's do some sanity checks */<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">安全检查</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (slave-&gt;offset &gt;= master-&gt;size) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* let's register it anyway to preserve ordering */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;offset = 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.size = 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk ("mtd: partition /"%s/" is out of reach -- disabled/n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
parts[i].name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (slave-&gt;offset + slave-&gt;mtd.size &gt; master-&gt;size) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.size = master-&gt;size - slave-&gt;offset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk ("mtd: partition /"%s/" extends beyond the end of device /"%s/" -- size truncated to %#x/n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
parts[i].name, master-&gt;name, slave-&gt;mtd.size);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (master-&gt;numeraseregions&gt;1) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Deal with variable erase size stuff */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_erase_region_info *regions = master-&gt;eraseregions;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Find the first erase regions which is part of this partition. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i &lt; master-&gt;numeraseregions &amp;&amp; slave-&gt;offset &gt;= regions[i].offset; i++)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i--; i &lt; master-&gt;numeraseregions &amp;&amp; slave-&gt;offset + slave-&gt;mtd.size &gt; regions[i].offset; i++) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (slave-&gt;mtd.erasesize &lt; regions[i].erasesize) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.erasesize = regions[i].erasesize;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
} else {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Single erase size */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.erasesize = master-&gt;erasesize;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if ((slave-&gt;mtd.flags &amp; MTD_WRITEABLE) &amp;&amp; </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
(slave-&gt;offset % slave-&gt;mtd.erasesize)) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Doesn't start on a boundary of major erase size */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.flags &amp;= ~MTD_WRITEABLE;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk ("mtd: partition /"%s/" doesn't start on an erase block boundary -- force read-only/n",parts[i].name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if ((slave-&gt;mtd.flags &amp; MTD_WRITEABLE) &amp;&amp; </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
(slave-&gt;mtd.size % slave-&gt;mtd.erasesize)) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave-&gt;mtd.flags &amp;= ~MTD_WRITEABLE;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk ("mtd: partition /"%s/" doesn't end on an erase block -- force read-only/n", parts[i].name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* register our partition */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
add_mtd_device(&amp;slave-&gt;mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862261"><span lang="EN-US">del_mtd_partitions</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int del_mtd_partitions(struct mtd_info *master)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/* </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* This function unregisters and destroy all slave MTD objects which are </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* attached to the given master MTD object.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/<span> </span>
</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">删除</span>
<span lang="EN-US">master</span>
<span style="">上的所有分区。</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">对</span>
<span lang="EN-US">mtd_partitions</span>
<span style="">上的每一个分区</span>
<span lang="EN-US">{</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US"><span> </span>
</span>
<span style="">如果它的主分区是</span>
<span lang="EN-US">master</span>
<span style="">,将它从</span>
<span lang="EN-US">mtd_partitions</span>
<span style="">和</span>
<span lang="EN-US">mtd_table</span>
<span style="">中删除并</span>
<span lang="EN-US">free</span>
<span style="">掉</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">}</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
master</span>
<span style="">:被删除分区的主分区</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
del_mtd_device()</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
kfree()</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
flash</span>
<span style="">相关的清除函数(</span>
<span lang="EN-US">maps</span>
<span style="">子目录下的文件中的</span>
<span lang="EN-US">cleanup_xxx</span>
<span style="">函数)</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct list_head *node;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_part *slave;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (node = mtd_partitions.next;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
node != &amp;mtd_partitions;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
node = node-&gt;next) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
slave = list_entry(node, struct mtd_part, list);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (slave-&gt;master == master) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct list_head *prev = node-&gt;prev;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
__list_del(prev, node-&gt;next);<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">从</span>
<span lang="EN-US">mtd_partitions</span>
<span style="">中删除</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
del_mtd_device(&amp;slave-&gt;mtd);<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">从</span>
<span lang="EN-US">mtd_table</span>
<span style="">中删除</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
kfree(slave);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
node = prev;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862262"><span lang="EN-US">part_read</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862263"><span lang="EN-US">part_write</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862264"><span lang="EN-US">part_readv</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862265"><span lang="EN-US">part_writev</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862266"><span lang="EN-US">part_erase</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862267"><span lang="EN-US">part_lock</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862268"><span lang="EN-US">part_unlock</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862269"><span lang="EN-US">part_sync</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862270"><span lang="EN-US">part_suspend</span>
</a>
</p>
<p class="MsoHeading7"><a name="_Toc7862271"><span lang="EN-US">part_resume</span>
</a>
</p>
<p class="MsoNormal"><strong><span style="">格式:</span>
</strong>
</p>
<p class="MsoNormal"><strong><span lang="EN-US"><span> </span>
</span>
</strong>
<span style="">略</span>
</p>
<p class="MsoNormal"><strong><span style="">注释:</span>
</strong>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/* </span>
</p>
<p class="MsoSalutation"><span style="color: blue;" lang="EN-US"><span></span>
* MTD methods which simply translate the effective address and pass through</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* to the _real_ device.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">非主分区的</span>
<span lang="EN-US">xxxx</span>
<span style="">函数。</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">进行安全性检查,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用主分区的</span>
<span lang="EN-US">xxxx</span>
<span style="">函数</span>
</p>
<p class="MsoNormal"><strong><span style="">参数:</span>
</strong>
</p>
<p class="MsoNormal"><strong><span lang="EN-US"><span> </span>
</span>
</strong>
<span style="">略</span>
</p>
<p class="MsoNormal"><strong><span style="">返回:</span>
</strong>
</p>
<p class="MsoNormal"><strong><span lang="EN-US"><span> </span>
</span>
</strong>
<span style="">略</span>
</p>
<p class="MsoNormal"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><strong><span lang="EN-US"><span> </span>
</span>
</strong>
<span style="">略</span>
</p>
<p class="MsoSalutation"><strong><span style="">被调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">在</span>
<span lang="EN-US">add_mtd_partitions</span>
<span style="">中被注册进非主分区的</span>
<span lang="EN-US">md_info</span>
</p>
<p class="MsoSalutation"><strong><span style="">源代码:</span>
</strong>
</p>
<p class="MsoNormal"><strong><span lang="EN-US"><span> </span>
</span>
</strong>
<span style="">略</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<h5>
<a name="_Toc7862272"><span lang="EN-US">mtdblock.c</span>
</a>
</h5>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
MTD</span>
<span style="">设备层的块设备的相关数据结构和程序,其中定义了</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的</span>
<span lang="EN-US">notifier</span>
<span style="">和</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的结构</span>
<span lang="EN-US">mtdblk_dev</span>
<span style="">类型的</span>
<strong><span lang="EN-US">mtdblks</span>
</strong>
<span style="">数组,该数组中的每个成员与</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备层的</span>
<span lang="EN-US">mtd_table</span>
<span style="">数组中的每个成员一一对应。</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862273"><span lang="EN-US">notifier</span>
</a>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">设备层的</span>
<span lang="EN-US">mtdblcok</span>
<span style="">设备的</span>
<span lang="EN-US">notifier </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">static struct mtd_notifier notifier = {<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_notify_add,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_notify_remove,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
NULL</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862274"><span lang="EN-US">mtdblk_dev</span>
</a>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">设备层的块设备的结构(</span>
<span lang="EN-US">and its private , I think</span>
<span style="">),</span>
<span lang="EN-US">MTD</span>
<span style="">字符设备没有相对应的结构。</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">struct mtdblk_dev {<span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *mtd; /* Locked */</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">下层原始设备层的</span>
<span lang="EN-US">MTD</span>
<span style="">设备结构</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int count;</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
<span style="color: blue;">struct semaphore cache_sem;</span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned char *cache_data;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">缓冲区(与</span>
<span lang="EN-US">MTD</span>
<span style="">设备块对齐)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long cache_offset;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">缓冲区内数据在原始设备层</span>
<span lang="EN-US">MTD</span>
<span style="">设备内的偏移</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int cache_size;<span> </span>
</span>
<span lang="EN-US"><span> </span>
</span>
<span style="">缓冲区大小(通常被设置为</span>
<span lang="EN-US">MTD</span>
<span style="">设备的</span>
<span lang="EN-US">erasesize</span>
<span style="">)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;<span> </span>
</span>
<span style="">缓冲区状态</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}<span> </span>
</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862275"><span lang="EN-US">mtdblks</span>
</a>
</p>
<p class="MsoNormal"><span style="">设备层(块)设备数组(与原始设备层的</span>
<span lang="EN-US">MAX_MTD_DEVICES</span>
<span style="">个</span>
<span lang="EN-US">MTD</span>
<span style="">设备一一对应)</span>
</p>
<p class="MsoNormal" style=""><span style="color: blue;" lang="EN-US">static struct mtdblk_dev *mtdblks[MAX_MTD_DEVICES];</span>
<span lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862276"><span lang="EN-US">erase_callback</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static void erase_callback(struct erase_info *done)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* Cache stuff...</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* Since typical flash erasable sectors are much larger than what Linux's</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* buffer cache can handle, we must implement read-modify-write on flash</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* sectors for each block write requests.<span> </span>
To avoid over-erasing flash sectors</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* and to speed things up, we locally cache a whole flash sector while it is</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* being written to until a different sector is required.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">回调函数,当写完时被调用。</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">在</span>
<span lang="EN-US">erase_write</span>
<span style="">中被赋给</span>
<span lang="EN-US">erase_info</span>
<span style="">结构</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
done</span>
<span style="">:</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
wake_up</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">在</span>
<span lang="EN-US">erase_write</span>
<span style="">中被注册</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
wait_queue_head_t *wait_q = (wait_queue_head_t *)done-&gt;priv;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
wake_up(wait_q);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862277"><span lang="EN-US">erase_write</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static int erase_write (struct mtd_info *mtd, unsigned long pos, <span> </span>
int len, const char *buf)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">擦除并写</span>
<span lang="EN-US">flash</span>
<span style="">。</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">1.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">声明一个</span>
<span lang="EN-US">erase_info</span>
<span style="">变量</span>
<span lang="EN-US">erase</span>
<span style="">并给其赋值,</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">2.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">调用原始设备层函数</span>
<span lang="EN-US">mtd_info-&gt;erase(mtd,erase)</span>
<span style="">,</span>
</p>
<p class="MsoNormal" style=""><span lang="EN-US">3.<span style='font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;'> </span>
</span>
<span style="">调用原始设备层函数</span>
<span lang="EN-US">mtd_info-&gt;write()</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd</span>
<span style="">:被操作的</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
pos</span>
<span style="">:</span>
<span lang="EN-US">MTD</span>
<span style="">原始设备的起始位置</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
len</span>
<span style="">:长度</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
buf</span>
<span style="">:被写入的内容</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
FIXME</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd_info-&gt;erase</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd_info-&gt;write</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
write_cached_data</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
do_cached_write</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct erase_info erase;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DECLARE_WAITQUEUE(wait, current);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
wait_queue_head_t wait_q;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
size_t retlen;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* First, let's erase the flash block.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
init_waitqueue_head(&amp;wait_q);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
erase.mtd = mtd;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
erase.callback = erase_callback;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
erase.addr = pos;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
erase.len = len;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
erase.priv = (u_long)&amp;wait_q;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
set_current_state(TASK_INTERRUPTIBLE);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
add_wait_queue(&amp;wait_q, &amp;wait);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = MTD_ERASE(mtd, &amp;erase);<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">调用</span>
<span lang="EN-US">mtd-&gt;erase()</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
set_current_state(TASK_RUNNING);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
remove_wait_queue(&amp;wait_q, &amp;wait);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
"on /"%s/" failed/n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
pos, len, mtd-&gt;name);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
schedule();<span> </span>
/* Wait for erase to finish. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
remove_wait_queue(&amp;wait_q, &amp;wait);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* Next, writhe data to flash.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = MTD_WRITE (mtd, pos, len, &amp;retlen, buf);<span> </span>
</span>
<span lang="EN-US">//</span>
<span style="">调用</span>
<span lang="EN-US">mtd-&gt;write()</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (retlen != len)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EIO;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862278"><span lang="EN-US">write_cached_data</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static int write_cached_data (struct mtdblk_dev *mtdblk)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">将指定设备层</span>
<span lang="EN-US">MTD</span>
<span style="">块设备缓冲区内的数据写入</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdblk</span>
<span style="">:指定的设备层</span>
<span lang="EN-US">MTD</span>
<span style="">块设备结构</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">失败:</span>
<span lang="EN-US">FIXME</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
erase_write()</span>
<span style="">写入</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
do_cached_write()</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdblock_release()</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdblock_ioctl()</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *mtd = mtdblk-&gt;mtd;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;cache_state != STATE_DIRTY)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for /"%s/" "</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
"at 0x%lx, size 0x%x/n", mtd-&gt;name, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_offset, mtdblk-&gt;cache_size);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = erase_write (mtd, mtdblk-&gt;cache_offset, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
mtdblk-&gt;cache_size, mtdblk-&gt;cache_data);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* Here we could argably set the cache state to STATE_CLEAN.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* However this could lead to inconsistency since we will not </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* be notified if this content is altered on the flash by other </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* means.<span> </span>
Let's declare it empty and leave buffering tasks to</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* the buffer cache instead.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_state = STATE_EMPTY;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862279"><span lang="EN-US">do_cached_write</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
int len, const char *buf)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">从</span>
<span lang="EN-US">buf</span>
<span style="">向指定的设备层</span>
<span lang="EN-US">MTD</span>
<span style="">块设备中缓冲写</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">如果缓冲区大小为</span>
<span lang="EN-US">0</span>
<span style="">,则调用</span>
<span lang="EN-US">mtd_info-&gt;write()</span>
<span style="">直接向</span>
<span lang="EN-US">MTD</span>
<span style="">设备中写,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">当(</span>
<span lang="EN-US">len&gt;0</span>
<span style="">)</span>
<span lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">如果是整块</span>
<span lang="EN-US">block</span>
<span style="">,则直接向</span>
<span lang="EN-US">MTD</span>
<span style="">设备中写</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">否则</span>
<span lang="EN-US">{</span>
</p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: 21pt;"><span style="">先调用</span>
<span lang="EN-US">write_cached_data()</span>
<span style="">将缓冲内的数据写入</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">在调用</span>
<span lang="EN-US">mtd_info-&gt;read</span>
<span style="">从</span>
<span lang="EN-US">MTD</span>
<span style="">设备中将对应块的数据读入缓冲</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">将</span>
<span lang="EN-US">buf</span>
<span style="">的数据(非整块)写入缓冲</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
len</span>
<span style="">自减</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdblk</span>
<span style="">:指定的</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
pos</span>
<span style="">:写入原始设备层</span>
<span lang="EN-US">MTD</span>
<span style="">设备的位置</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
len</span>
<span style="">:数据长度</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
buf</span>
<span style="">:被写入的数据</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">失败:返回错误码</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
erase_write()</span>
<span style="">用于直接写</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
write_cached_data()</span>
<span style="">用于清空</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的缓冲区</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd_info-&gt;read()</span>
<span style="">用于从</span>
<span lang="EN-US">MTD</span>
<span style="">设备中读数据</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd_info-&gt;write()</span>
<span style="">用于向</span>
<span lang="EN-US">MTD</span>
<span style="">设备中写数据</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
handle_mtdblock_request()</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *mtd = mtdblk-&gt;mtd;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int sect_size = mtdblk-&gt;cache_size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
size_t retlen;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on /"%s/" at 0x%lx, size 0x%x/n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd-&gt;name, pos, len);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!sect_size)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return MTD_WRITE (mtd, pos, len, &amp;retlen, buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
while (len &gt; 0) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long sect_start = (pos/sect_size)*sect_size;//we should write by erase block</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int offset = pos - sect_start;//real start address</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int size = sect_size - offset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if( size &gt; len ) </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
size = len;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (size == sect_size) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* We are covering a whole sector.<span> </span>
Thus there is no</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* need to bother with the cache while it may still be</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* useful for other partial writes.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = erase_write (mtd, pos, size, buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
} else {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Partial sector: need to use the cache */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;cache_state == STATE_DIRTY &amp;&amp;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
mtdblk-&gt;cache_offset != sect_start) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = write_cached_data(mtdblk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret) </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;cache_state == STATE_EMPTY ||</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
mtdblk-&gt;cache_offset != sect_start) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* fill the cache with the current sector */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_state = STATE_EMPTY;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = MTD_READ(mtd, sect_start, sect_size, &amp;retlen, mtdblk-&gt;cache_data);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (retlen != sect_size)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EIO;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_offset = sect_start;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_size = sect_size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_state = STATE_CLEAN;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* write data to our local cache */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
memcpy (mtdblk-&gt;cache_data + offset, buf, size);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_state = STATE_DIRTY;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
buf += size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
pos += size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
len -= size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862280"><span lang="EN-US">do_cached_read</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
int len, char *buf)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">从指定的</span>
<span lang="EN-US">MTD</span>
<span style="">块设备中缓冲读到指定位置</span>
<span lang="EN-US">buf</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">如果缓冲区大小为</span>
<span lang="EN-US">0</span>
<span style="">,调用</span>
<span lang="EN-US">mtd_info-&gt;read()</span>
<span style="">直接从原始设备层</span>
<span lang="EN-US">MTD</span>
<span style="">设备中读取</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">否则当(</span>
<span lang="EN-US">len&gt;0</span>
<span style="">)</span>
<span lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">如果缓冲区不为空且其中数据正好是所需数据,则从缓冲区拷贝到</span>
<span lang="EN-US">buf</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">否则调用</span>
<span lang="EN-US">mtd_info-&gt;read()</span>
<span style="">从</span>
<span lang="EN-US">MTD</span>
<span style="">中读</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdblk</span>
<span style="">:指定的</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
pos</span>
<span style="">:</span>
<span lang="EN-US">MTD</span>
<span style="">设备中指定的位置</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
len</span>
<span style="">:长度</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
buf</span>
<span style="">:被写入的地址</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">失败:返回错误码</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtd_info-&gt;read()</span>
<span style="">从指定的</span>
<span lang="EN-US">MTD</span>
<span style="">设备中读</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
handle_mtdblock_request()</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *mtd = mtdblk-&gt;mtd;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int sect_size = mtdblk-&gt;cache_size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
size_t retlen;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on /"%s/" at 0x%lx, size 0x%x/n", </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd-&gt;name, pos, len);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!sect_size)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return MTD_READ (mtd, pos, len, &amp;retlen, buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
while (len &gt; 0) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned long sect_start = (pos/sect_size)*sect_size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int offset = pos - sect_start;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int size = sect_size - offset;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (size &gt; len) </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
size = len;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/*</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* Check if the requested data is already cached</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* Read the requested amount of data from our internal cache if it</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* contains what we want, otherwise we read the data directly</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
* from flash.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span></span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;cache_state != STATE_EMPTY &amp;&amp;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
mtdblk-&gt;cache_offset == sect_start) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
memcpy (buf, mtdblk-&gt;cache_data + offset, size);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
} else {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ret = MTD_READ (mtd, pos, size, &amp;retlen, buf);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (ret)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return ret;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (retlen != size)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EIO;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
buf += size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
pos += size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
len -= size;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862281"><span lang="EN-US">mtdblock_open</span>
</a>
</p>
<p class="MsoNormal"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static int mtdblock_open(struct inode *inode, struct file *file)</span>
</p>
<p class="MsoNormal"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoNormal"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">打开一个</span>
<span lang="EN-US">MTD</span>
<span style="">块设备(设备层)</span>
</p>
<p class="MsoNormal"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">获得指定节点在原始设备层的</span>
<span lang="EN-US">MTD</span>
<span style="">设备(</span>
<span lang="EN-US">mtd_table</span>
<span style="">),</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">如果</span>
<span style="">其在设备层的对应块设备(</span>
<span lang="EN-US">mtdblks</span>
<span style="">)被打开,返回,</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">否则</span>
<span style="">将其打开并初始化,</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">将</span>
<span lang="EN-US">MTD</span>
<span style="">设备的大小</span>
<span lang="EN-US">/1024</span>
<span style="">赋给对应的</span>
<span lang="EN-US">mtd_sizes</span>
<span style="">,</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">将</span>
<span lang="EN-US">MTD</span>
<span style="">设备的</span>
<span lang="EN-US">erasesize</span>
<span style="">和</span>
<span lang="EN-US">PAGE_SIZE</span>
<span style="">中较小的一个赋给对应的</span>
<span lang="EN-US">mtd_blksizes</span>
<span style="">。</span>
</p>
<p class="MsoNormal"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
inode</span>
<span style="">:指定的索引节点</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
file</span>
<span style="">:没用</span>
</p>
<p class="MsoNormal"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">失败:返回错误码</span>
</p>
<p class="MsoNormal"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
get_mtd_device()</span>
<span style="">和</span>
<span lang="EN-US">put_mtd_device()</span>
<span style="">获取原始设备层的</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
<span lang="EN-US"> </span>
</p>
<p class="MsoNormal"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">注册进</span>
<span lang="EN-US">mtd_fops</span>
<span style="">结构</span>
</p>
<p class="MsoNormal"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtdblk_dev *mtdblk;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtd_info *mtd;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int dev;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open/n");</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!inode)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EINVAL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
dev = MINOR(inode-&gt;i_rdev);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (dev &gt;= MAX_MTD_DEVICES)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EINVAL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_INC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd = get_mtd_device(NULL, dev);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!mtd)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -ENODEV;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (MTD_ABSENT == mtd-&gt;type) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
put_mtd_device(mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_DEC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
return -ENODEV;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* If it's already open, no need to piss about. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblks[dev]) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblks[dev]-&gt;count++;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* OK, it's not open. Try to find it */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* First we have to drop the lock, because we have to</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
to things which might sleep.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
*/</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!mtdblk) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
put_mtd_device(mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_DEC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -ENOMEM;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
memset(mtdblk, 0, sizeof(*mtdblk));</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;count = 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;mtd = mtd;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
init_MUTEX (&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_state = STATE_EMPTY;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if ((mtdblk-&gt;mtd-&gt;flags &amp; MTD_CAP_RAM) != MTD_CAP_RAM &amp;&amp;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
mtdblk-&gt;mtd-&gt;erasesize) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_size = mtdblk-&gt;mtd-&gt;erasesize;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;cache_data = vmalloc(mtdblk-&gt;mtd-&gt;erasesize);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!mtdblk-&gt;cache_data) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
put_mtd_device(mtdblk-&gt;mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
kfree(mtdblk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_DEC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -ENOMEM;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* OK, we've created a new one. Add it to the list. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblks[dev]) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Another CPU made one at the same time as us. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblks[dev]-&gt;count++;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
put_mtd_device(mtdblk-&gt;mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
vfree(mtdblk-&gt;cache_data);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
kfree(mtdblk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblks[dev] = mtdblk;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_sizes[dev] = mtdblk-&gt;mtd-&gt;size/1024;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;mtd-&gt;erasesize)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_blksizes[dev] = mtdblk-&gt;mtd-&gt;erasesize;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtd_blksizes[dev] &gt; PAGE_SIZE)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_blksizes[dev] = PAGE_SIZE;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
set_device_ro (inode-&gt;i_rdev, !(mtdblk-&gt;mtd-&gt;flags &amp; MTD_WRITEABLE));</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(MTD_DEBUG_LEVEL1, "ok/n");</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862282"><span lang="EN-US">mtdblock_release</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static release_t mtdblock_release(struct inode *inode, struct file *file)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">释放一个设备层的</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">write_cached_data</span>
<span style="">刷新缓冲区,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">将</span>
<span lang="EN-US">MTD</span>
<span style="">块设备使用数减</span>
<span lang="EN-US">1</span>
<span style="">,如果变为</span>
<span lang="EN-US">0</span>
<span style="">,释放原始设备层的</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
inode</span>
<span style="">:指定的索引节点</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
file</span>
<span style="">:无用</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
inode</span>
<span style="">为</span>
<span lang="EN-US">NULL</span>
<span style="">:返回</span>
<span lang="EN-US">-ENODEV</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
write_cached_data()</span>
<span style="">刷新缓冲</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
put_mtd_device()</span>
<span style="">释放</span>
<span lang="EN-US">MTD</span>
<span style="">设备</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">注册进</span>
<span lang="EN-US">mtd_fops</span>
<span style="">结构</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int dev;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtdblk_dev *mtdblk;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release/n");</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (inode == NULL)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
release_return(-ENODEV);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
invalidate_device(inode-&gt;i_rdev, 1);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
dev = MINOR(inode-&gt;i_rdev);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk = mtdblks[dev];</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
write_cached_data(mtdblk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!--mtdblk-&gt;count) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* It was the last usage. Free the device */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblks[dev] = NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;mtd-&gt;sync)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;mtd-&gt;sync(mtdblk-&gt;mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
put_mtd_device(mtdblk-&gt;mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
vfree(mtdblk-&gt;cache_data);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
kfree(mtdblk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
} else {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DEBUG(MTD_DEBUG_LEVEL1, "ok/n");</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MOD_DEC_USE_COUNT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
release_return(0);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}<span> </span>
</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862283"><span lang="EN-US">handle_mtdblock_request</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static void handle_mtdblock_request(void)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">/* </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* This is a special request_fn because it is executed in a process context </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* to be able to sleep independently of the caller.<span> </span>
The io_request_lock </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* is held upon entry and exit.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* The head of our request queue is considered active so there is no need </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
* to dequeue requests before we are done.</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span></span>
*/</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">处理对</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的请求</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">获取当前请求,分情况处理</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
do_cached_read()</span>
<span style="">处理读请求</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
do_cached_write()</span>
<span style="">处理写请求</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
mtdblock_thread()</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct request *req;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtdblk_dev *mtdblk;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unsigned int res;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (;;) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
INIT_REQUEST;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
req = CURRENT;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock_irq(&amp;io_request_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk = mtdblks[MINOR(req-&gt;rq_dev)];</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
res = 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (MINOR(req-&gt;rq_dev) &gt;= MAX_MTD_DEVICES)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
panic(__FUNCTION__": minor out of bound");</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if ((req-&gt;sector + req-&gt;current_nr_sectors) &gt; (mtdblk-&gt;mtd-&gt;size &gt;&gt; 9))</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
goto end_req;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
// Handle the request</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
switch (req-&gt;cmd)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int err;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
case READ:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
err = do_cached_read (mtdblk, req-&gt;sector &lt;&lt; 9, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
req-&gt;current_nr_sectors &lt;&lt; 9,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
req-&gt;buffer);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!err)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
res = 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
break;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
case WRITE:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
// Read only device</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if ( !(mtdblk-&gt;mtd-&gt;flags &amp; MTD_WRITEABLE) ) </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
break;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
// Do the write</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
err = do_cached_write (mtdblk, req-&gt;sector &lt;&lt; 9,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
req-&gt;current_nr_sectors &lt;&lt; 9, </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
req-&gt;buffer);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!err)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
res = 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
break;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">end_req:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock_irq(&amp;io_request_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
end_request(res);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862284"><span lang="EN-US">leaving</span>
</a>
</p>
<p class="MsoNormal" style=""><span style="color: blue;" lang="EN-US">static volatile int leaving = 0;<span> </span>
</span>
<span style="">控制线程的变量,在</span>
<span lang="EN-US">mtdblock_thread</span>
<span style="">作为测试条件,在</span>
<span lang="EN-US">cleanup_mtdblock</span>
<span style="">中被赋</span>
<span lang="EN-US">1</span>
</p>
<p class="MsoHeading7"><a name="_Toc7862285"><span lang="EN-US">mtdblock_thread</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int mtdblock_thread(void *dummy)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">启动一个</span>
<span lang="EN-US">MTD</span>
<span style="">块设备线程</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">handle_mtdblock_request()</span>
<span style="">处理对</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的读写</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
dummy</span>
<span style="">:</span>
<span lang="EN-US">FIXME</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">线程结束:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoSalutation"><strong><span style="">调用:</span>
</strong>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
handle_mtdblock_request()</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
init_mtdblock()</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct task_struct *tsk = current;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
DECLARE_WAITQUEUE(wait, tsk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
tsk-&gt;session = 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
tsk-&gt;pgrp = 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* we might get involved when memory gets low, so use PF_MEMALLOC */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
tsk-&gt;flags |= PF_MEMALLOC;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
strcpy(tsk-&gt;comm, "mtdblockd");</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
tsk-&gt;tty = NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock_irq(&amp;tsk-&gt;sigmask_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
sigfillset(&amp;tsk-&gt;blocked);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
recalc_sigpending(tsk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock_irq(&amp;tsk-&gt;sigmask_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
exit_mm(tsk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
exit_files(tsk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
exit_sighand(tsk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
exit_fs(tsk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
while (!leaving) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
add_wait_queue(&amp;thr_wq, &amp;wait);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
set_current_state(TASK_INTERRUPTIBLE);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock_irq(&amp;io_request_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (QUEUE_EMPTY || QUEUE_PLUGGED) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock_irq(&amp;io_request_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
schedule();</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
remove_wait_queue(&amp;thr_wq, &amp;wait); </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
} else {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
remove_wait_queue(&amp;thr_wq, &amp;wait); </span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
set_current_state(TASK_RUNNING);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
handle_mtdblock_request();</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_unlock_irq(&amp;io_request_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;thread_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862286"><span lang="EN-US">mtdblock_ioctl</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="color: blue;" lang="EN-US">static int mtdblock_ioctl(struct inode * inode, struct file * file,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
unsigned int cmd, unsigned long arg)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">对</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的</span>
<span lang="EN-US">IO</span>
<span style="">控制</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
FIXME</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">失败:返回错误码</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
write_cached_data()</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">被注册进</span>
<span lang="EN-US">mtd_fops</span>
<span style="">结构</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
struct mtdblk_dev *mtdblk;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk = mtdblks[MINOR(inode-&gt;i_rdev)];</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#ifdef PARANOIA</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (!mtdblk)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
BUG();</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#endif</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
switch (cmd) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
case BLKGETSIZE:<span> </span>
/* Return device size */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return put_user((mtdblk-&gt;mtd-&gt;size &gt;&gt; 9), (long *) arg);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#ifdef BLKGETSIZE64</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
case BLKGETSIZE64:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return put_user((u64)mtdblk-&gt;mtd-&gt;size, (u64 *)arg);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#endif</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
case BLKFLSBUF:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,2,0)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if(!capable(CAP_SYS_ADMIN))</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EACCES;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#endif</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
fsync_dev(inode-&gt;i_rdev);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
invalidate_buffers(inode-&gt;i_rdev);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
write_cached_data(mtdblk);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
up(&amp;mtdblk-&gt;cache_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (mtdblk-&gt;mtd-&gt;sync)</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtdblk-&gt;mtd-&gt;sync(mtdblk-&gt;mtd);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
default:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EINVAL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862287"><span lang="EN-US">mtd_fops</span>
</a>
</p>
<p class="MsoNormal"><span style="">对</span>
<span lang="EN-US">MTD</span>
<span style="">块设备操作的函数结构</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">static struct block_device_operations mtd_fops = <span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
open: mtdblock_open,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
release: mtdblock_release,</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
ioctl: mtdblock_ioctl</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">};</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862288"><span lang="EN-US">init_mtdblock</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int __init init_mtdblock(void)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">初始化</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">如果定义了</span>
<span lang="EN-US">CONFIG_DEVFS_FS{</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">devfs_register_blkdev()</span>
<span style="">注册块设备,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">register_mtd_user()</span>
<span style="">将设备层</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的</span>
<span lang="EN-US">notifier</span>
<span style="">注册进原始设备层</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">}</span>
</p>
<p class="MsoNormal" style="margin-left: 21pt;"><span style="">否则调用</span>
<span lang="EN-US">register_blkdev()</span>
<span style="">注册块设备,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">初始化</span>
<span lang="EN-US">mtd_sizes</span>
<span style="">和</span>
<span lang="EN-US">mtd_blksizes</span>
<span style="">数组,</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">启动</span>
<span lang="EN-US">mtdblock_thread</span>
<span style="">线程</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">成功:返回</span>
<span lang="EN-US">0</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">注册块设备失败:返回</span>
<span lang="EN-US">-EAGAIN</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
kernel_thread()</span>
<span style="">启动</span>
<span lang="EN-US">mtdblock_thread</span>
<span style="">线程</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
register_blkdev()</span>
<span style="">注册块设备</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
module_init</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
__init</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
int i;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
spin_lock_init(&amp;mtdblks_lock);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#ifdef CONFIG_DEVFS_FS</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &amp;mtd_fops))</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices./n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
MTD_BLOCK_MAJOR);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EAGAIN;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
register_mtd_user(&amp;notifier);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#else</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
if (register_blkdev(MAJOR_NR,DEVICE_NAME,&amp;mtd_fops)) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices./n",</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
<span> </span>
MTD_BLOCK_MAJOR);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return -EAGAIN;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#endif</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* We fill it in at open() time. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
for (i=0; i&lt; MAX_MTD_DEVICES; i++) {</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_sizes[i] = 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
mtd_blksizes[i] = BLOCK_SIZE;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
init_waitqueue_head(&amp;thr_wq);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
/* Allow the block size to default to BLOCK_SIZE. */</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
blksize_size[MAJOR_NR] = mtd_blksizes;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
blk_size[MAJOR_NR] = mtd_sizes;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &amp;mtdblock_request);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
return 0;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">}</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"></span>
</p>
<p class="MsoHeading7"><a name="_Toc7862289"><span lang="EN-US">cleanup_mtdblock</span>
</a>
</p>
<p class="MsoIndexHeading"><span style="">格式:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
static void __exit cleanup_mtdblock(void)</span>
</p>
<p class="MsoIndexHeading"><span style="">注释:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">功能:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">清除</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoIndexHeading"><span style="">说明:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">如果定义了</span>
<span lang="EN-US">CONFIG_DEVFS_FS{</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">unregister_mtd_user()</span>
<span style="">注销</span>
<span lang="EN-US">MTD</span>
<span style="">块设备的</span>
<span lang="EN-US">notifier</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">调用</span>
<span lang="EN-US">devfs_unregister_blkdev()</span>
<span style="">注销</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
}</span>
</p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="">否则调用</span>
<span lang="EN-US">unregister_blkdev()</span>
<span style="">注销</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoIndexHeading"><span style="">参数:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">返回:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
</span>
<span style="">无</span>
</p>
<p class="MsoIndexHeading"><span style="">调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
unregister_blkdev()</span>
<span style="">注销</span>
<span lang="EN-US">MTD</span>
<span style="">块设备</span>
</p>
<p class="MsoIndexHeading"><span style="">被调用:</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
__exit</span>
</p>
<p class="MsoNormal"><span lang="EN-US"><span> </span>
module_exit</span>
</p>
<p class="MsoIndexHeading"><span style="">源代码:</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">{</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
leaving = 1;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
wake_up(&amp;thr_wq);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
down(&amp;thread_sem);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#ifdef CONFIG_DEVFS_FS</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unregister_mtd_user(&amp;notifier);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
devfs_unregister(devfs_dir_handle);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#else</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
unregister_blkdev(MAJOR_NR,DEVICE_NAME);</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US">#endif</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
blksize_size[MAJOR_NR] = NULL;</span>
</p>
<p class="MsoNormal"><span style="color: blue;" lang="EN-US"><span> </span>
blk_size[MAJOR_NR] = NULL;</span>
</p>
<p>
<span style="color: blue;" lang="EN-US">}</span>
</p>
分享到:
评论

相关推荐

    linux MTD源码分析

    用于实现嵌入式linux系统构建的MTD驱动部分,源代码分析,非常有意义的。

    linux MTD源码学习报告.doc

    linux MTD源码学习报告.doc mtd源代码分析

    Linux MTD源代码分析

    Linux MTD源代码分析 Linux MTD源代码分析

    linuxMTD源代码分析

    Jim Zeus经典的mtd源码分析,网页版看起来比较舒服:)

    雷达分析与设计MATLAB源码

    《雷达分析与设计》课本相关MATLAB仿真源码。 涵盖阵列信号处理、杂波处理、脉冲压缩、匹配滤波、MTD、等多种信号处理方法。资源众多

    雷达信号CFAR处理-MATLAB源码

    【资源内容】利用MATLAB软件分析了回波信号的脉压、MTD、CFAR(重点)处理内容。可以仿真任意多目标。另附PDF文件详细解释CFAR实现过程。 【适应对象】雷达专业、信号处理专业学生。 【算法说明】脉压部分采用FFT/...

    郭天祥ARM9视频教程(第13和20讲均可观看).docx

    1. 内核源码目录结构分析 2. Makefile,Kconfig文件分析 3. Linux启动过程分析 4. 配置、编译内核 第十六讲 向内核中加入驱动 1. 支持NAND和yaffs2,挂载文件系统 2. 基本外围设备的配置(LCD、触摸屏、网卡、声卡,...

    脉冲多普勒雷达信号处理MATLAB源码

    仿真内容: 仿真脉冲多卜勒雷达的信号处理。设脉冲宽度为各学生学号末两位数,单位为μs,重复周期为200μs,雷达载频为10GHz,输入噪声为高斯白噪声。目标模拟分单目标和双目标...2021 11 12:脉压增益分析的BUG已修复

    Android技术内幕.系统卷

    具体而言,系统卷第1章首先从宏观上介绍了Android系统的架构以及各个层次之间的关系,然后介绍了如何获取Android源代码并搭建Android源代码开发环境和阅读环境的方法;第2章有针对性地剖析了Android的内核机制和结构...

    Android技术内幕.系统卷(扫描版)

    第1章 准备工作 /1 1.1 深入认识android /2 1.1.1 android的系统构架 /2 1.1.2 android的初始化流程 /5 1.1.3 各个层次之间的相互关系 /8 1.1.4 android系统开发(移植)和应用开发 /11 1.2 获取和编译android的源码...

    Android技术内幕:系统卷.pdf 详细书签

     具体而言,系统卷第1章首先从宏观上介绍了Android系统的架构以及各个层次之间的关系,然后介绍了如何获取Android源代码并搭建Android源代码开发环境和阅读环境的方法;第2章有针对性地剖析了Android的内核机制和...

    Android技术内幕.系统卷 pdf

    第1章 准备工作 /1 1.1 深入认识android /2 1.1.1 android的系统构架 /2 1.1.2 android的初始化流程 /5 1.1.3 各个层次之间的相互关系 /8 1.1.4 android系统开发(移植)和应用开发 /11 1.2 获取和编译android...

    Linux 2.6.24 内核注解

    增加了mtd层的注解,顺带引出了block文件夹中的注解 若代码和头文件中注解有不一致的,以头文件的注解为准, 因为都是一边看一边加注的,经常会出现第一次理解不对的情况,而后的修改,再追溯到最初的位置,工作量...

    LFM脉冲雷达信号处理流程仿真MATLAB源码

    仿真内容: 仿真线性调频脉冲雷达的信号处理。设线性调频带宽为各学生学号末两位数,单位为MHz,时宽为200μs,占空比10%,雷达载频为10GHz,输入噪声为高斯白噪声。...2021 11 12:脉压增益分析BUG已修复

    uboott移植实验手册及技术文档

    (2)进入 U-Boot源码目录 #cd u-boot-1.3.1 (3)创建自己的开发板: #cd board #cp smdk2410 fs2410 –a #cd fs2410 #mv smdk2410.c fs2410.c #vi Makefile (将 smdk2410修改为 fs2410) #cd ../../...

    LINUX系统开发技术详解---基于ARM

    9 2.1.2 ARM处理器体系结构........................................................................................ 10 2.1.3 Linux 与ARM处理器...............................................................

Global site tag (gtag.js) - Google Analytics