⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block_io_subsystem.html

📁 ADI 公司blackfin系列的用户使用文挡。
💻 HTML
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head>  <title></title>  <link rel="stylesheet" media="screen" type="text/css" href="./style.css" />  <link rel="stylesheet" media="screen" type="text/css" href="./design.css" />  <link rel="stylesheet" media="print" type="text/css" href="./print.css" />  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><a href=start.html>start</a></br><div class="toc"><div class="tocheader toctoggle" id="toc__header">Table of Contents</div><div id="toc__inside"><ul class="toc"><li class="clear"><ul class="toc"><li class="level2"><div class="li"><span class="li"><a href="#kernel_2.6_device_drivers_block_i_o_structure" class="toc">Kernel 2.6 Device Drivers, Block I/O structure</a></span></div><ul class="toc"><li class="level3"><div class="li"><span class="li"><a href="#key_elements_of_the_bio_structure" class="toc">Key elements of the bio structure</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#the_bio_vec_structure" class="toc">The BIO Vec Structure</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#bio_references" class="toc">BIO References</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#bio_example_use" class="toc">BIO Example Use</a></span></div></li></ul></li></ul></li></ul></div></div><h2><a name="kernel_2.6_device_drivers_block_i_o_structure" id="kernel_2.6_device_drivers_block_i_o_structure">Kernel 2.6 Device Drivers, Block I/O structure</a></h2><div class="level2"><p> The BIO structure provides a way to handle the different data delivery mechanisms required for some block driver I/O systems.</p><p>The BIO structure encapsulates the data structures to be written to or read from the device and the device specific access routines. Buffered IO requests to block devices use a generic <strong>request</strong> structure. Under 2.4 kernels this used a statically defined <strong>buffer head</strong> structure to define the data to be transferred.</p><p>In the 2.6 Driver model the <strong>buffer head</strong> structure  has now been replaced by the <strong>optional</strong> BIO structure to allow more flexibility in defining the data and any transfer characteristics to the I/O device.</p></div><!-- SECTION [1-720] --><h3><a name="key_elements_of_the_bio_structure" id="key_elements_of_the_bio_structure">Key elements of the bio structure</a></h3><div class="level3"><p>This is the main unit of I/O for the block layer and lower layers (ie drivers and stacking drivers)</p><pre class="code c">  from      linux/include/bio.<span class="me1">h</span>&nbsp;  <span class="kw4">struct</span> bio <span class="br0">&#123;</span>      sector_t                  bi_sector;      <span class="kw4">struct</span> bio                *bi_next;       <span class="coMULTI">/* request queue link */</span>      <span class="kw4">struct</span> block_device       *bi_bdev;      <span class="kw4">unsigned</span> <span class="kw4">long</span>             bi_flags;       <span class="coMULTI">/* status, command, etc */</span>      <span class="kw4">unsigned</span> <span class="kw4">long</span>             bi_rw;          <span class="coMULTI">/* bottom bits READ/WRITE,                                                 * top bits priority                                                 */</span>      <span class="kw4">unsigned</span> <span class="kw4">short</span>            bi_vcnt;        <span class="coMULTI">/* how many bio_vec's */</span>      <span class="kw4">unsigned</span> <span class="kw4">short</span>            bi_idx;  <span class="coMULTI">/* current index into bvl_vec */</span>     <span class="coMULTI">/* Number of segments in this BIO after       * physical address coalescing is performed.       */</span>      <span class="kw4">unsigned</span> <span class="kw4">short</span>            bi_phys_segments;&nbsp;       <span class="coMULTI">/* Number of segments after physical and DMA remapping       * hardware coalescing is performed.       */</span>      <span class="kw4">unsigned</span> <span class="kw4">short</span>            bi_hw_segments;&nbsp;      <span class="kw4">unsigned</span> <span class="kw4">int</span>              bi_size;        <span class="coMULTI">/* residual I/O count */</span>      <span class="kw4">unsigned</span> <span class="kw4">int</span>              bi_max_vecs;    <span class="coMULTI">/* max bvl_vecs we can hold */</span>&nbsp;      <span class="kw4">struct</span> bio_vec            *bi_io_vec;     <span class="coMULTI">/* the actual vec list */</span>&nbsp;      bio_end_io_t              *bi_end_io;      atomic_t                  bi_cnt;         <span class="coMULTI">/* pin count */</span>&nbsp;      <span class="kw4">void</span>                      *bi_private;&nbsp;      bio_destructor_t  *bi_destructor; <span class="coMULTI">/* destructor */</span>   <span class="br0">&#125;</span>;</pre></div><!-- SECTION [721-2277] --><h3><a name="the_bio_vec_structure" id="the_bio_vec_structure">The BIO Vec Structure</a></h3><div class="level3"><p>This is a list of data pages that are to be read from or written to the device.</p><p>A BIO service will process each page in the list according to the specific requirements of the device.</p><pre class="code c"> from      linux/include/bio.<span class="me1">h</span>&nbsp;   <span class="kw4">struct</span> bio_vec <span class="br0">&#123;</span>      <span class="kw4">struct</span> page       *bv_page;      <span class="kw4">unsigned</span> <span class="kw4">int</span>      bv_len;      <span class="kw4">unsigned</span> <span class="kw4">int</span>      bv_offset;   <span class="br0">&#125;</span>;</pre></div><!-- SECTION [2278-2674] --><h3><a name="bio_references" id="bio_references">BIO References</a></h3><div class="level3"><p> Look in the following files for more details</p><pre class="code">      linux/include/bio.h      Documentation/block/biodoc.txt</pre></div><!-- SECTION [2675-2827] --><h3><a name="bio_example_use" id="bio_example_use">BIO Example Use</a></h3><div class="level3"><p>This outline example is taken from the MTD flash driver. There are some special requirements for this driver due to the nature of flash devices.</p><p>Refer to the code in <strong>drivers/mtd/mtdblock.c</strong> driver for more details.</p><p>Setting up a list of BIO&rsquo;s for data output </p><ul><li class="level1"><div class="li"> If the data starts in the middle of a block then read the old data and</div></li></ul><p>overwrite the end of the block with the new data.</p><ul><li class="level1"><div class="li"> If the data starts on a page boundary and fills the page then grab a page</div></li></ul><p>from the page cache</p><ul><li class="level1"><div class="li"> If the data starts on a page boundary and does not fill the page then</div></li></ul><p>read the old data and overwrite the start of the block with the new data.</p><ul><li class="level1"><div class="li"> grab a page</div></li></ul><p>As each page is created with the correct data it is added to the list of pages to be processed by the BIO.</p><pre class="code">      bio = blkmtd_add_page(bio, dev-&gt;blkdev, page, pagecnt);[...]      bio_add_page(bio, page, PAGE_SIZE, 0);</pre><p>The data is written to the device using the submit_bio</p><pre class="code">     (in ll_rw_blk.c) function</pre><pre class="code c">&nbsp;       <span class="kw4">struct</span> completion event;&nbsp;      init_completion<span class="br0">&#40;</span>&amp;event<span class="br0">&#41;</span>;      bio-&gt;bi_private = &amp;event;      bio-&gt;bi_end_io = bi_write_complete;      submit_bio<span class="br0">&#40;</span>WRITE_SYNC, bio<span class="br0">&#41;</span>;      wait_for_completion<span class="br0">&#40;</span>&amp;event<span class="br0">&#41;</span>;             <span class="br0">&#40;</span> see bio_endio in bio.<span class="me1">c</span> <span class="br0">&#41;</span>&nbsp;</pre><p> This in turn will call: </p><pre class="code c">&nbsp;&nbsp;     generic_make_request<span class="br0">&#40;</span>bio<span class="br0">&#41;</span>; <span class="co1">// function</span>        <span class="br0">&#40;</span> ll_rw_blk.<span class="me1">c</span> <span class="br0">&#41;</span>&nbsp;</pre><p>This in turn will call the <strong>make_request_fn</strong> for the Device I/O Queue.</p><p>  </p><pre class="code c">&nbsp;      <span class="kw4">int</span> ret;      request_queue_t *q&nbsp;      <span class="co1">// this gets the gendisk queue</span>      q = bdev_get_queue<span class="br0">&#40;</span>bio-&gt;bi_bdev<span class="br0">&#41;</span>;         <span class="br0">&#40;</span> this is returns bdev-&gt;bd_disk-&gt;queue <span class="br0">&#41;</span>      <span class="kw1">do</span> <span class="br0">&#123;</span>          ret = q-&gt;make_request_fn<span class="br0">&#40;</span>q, bio<span class="br0">&#41;</span>;           <span class="br0">&#40;</span> see ll_rw_blk.<span class="me1">c</span> <span class="br0">&#41;</span>         <span class="br0">&#125;</span> <span class="kw1">while</span><span class="br0">&#40;</span>ret<span class="br0">&#41;</span>;&nbsp;</pre></div><!-- SECTION [2828-] --></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -