55.html
来自「linux 0.11中文版 有注释」· HTML 代码 · 共 661 行 · 第 1/5 页
HTML
661 行
<a name='L233'> <b>goto</b> repeat;
<a name='L234'><i><font color='green'>// 取数字输入寄存器值,如果最高位(位7)置位,则表示软盘已更换,此时关闭马达并退出返回1。</font></i>
<a name='L235'><i><font color='green'>// 否则关闭马达退出返回0。</font></i>
<a name='L236'> <b>if</b> (<a href='../D/842.html' title='Multiple defined in 2 places.'>inb</a> (FD_DIR) & 0x80)
<a name='L237'> <font color='red'>{</font>
<a name='L238'> <a href='../S/74.html#L342' title='Defined at 342 in kernel/sched.c.'>floppy_off</a> (nr);
<a name='L239'> <b>return</b> 1;
<a name='L240'> <font color='red'>}</font>
<a name='L241'> <a href='../S/74.html#L342' title='Defined at 342 in kernel/sched.c.'>floppy_off</a> (nr);
<a name='L242'> <b>return</b> 0;
<a name='L243'><font color='red'>}</font>
<a name='L244'>
<a name='L245'><i><font color='green'>//// 复制内存块。</font></i>
<a name='L246'><font color='darkred'>#define</font> <a href='../R/407.html' title='Multiple refered from 2 places.'>copy_buffer</a>(from,to) \
<a name='L247'> <b>__asm__</b>( "cld ; rep ; movsl" \
<a name='L248'> :: "c" (<a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>/4), "S" ((<b>long</b>)(from)), "D" ((<b>long</b>)(to)) \
<a name='L249'> : "cx", "di", "si")
<a name='L250'>
<a name='L251'><i><font color='green'>//// 设置(初始化)软盘DMA 通道。</font></i>
<a name='L252'><b>static</b> <b>void</b>
<a name='L253'><a href='../S/55.html#L415' title='Refered from 415 in kernel/blk_drv/floppy.c.'>setup_DMA</a> (<b>void</b>)
<a name='L254'><font color='red'>{</font>
<a name='L255'> <b>long</b> addr = (<b>long</b>) <a href='../S/54.html#L116' title='Defined at 116 in kernel/blk_drv/blk.h.'>CURRENT</a>->buffer; <i><font color='green'>// 当前请求项缓冲区所处内存中位置(地址)。</font></i>
<a name='L256'>
<a name='L257'> <a href='../S/25.html#L15' title='Defined at 15 in include/asm/system.h.'>cli</a> ();
<a name='L258'><i><font color='green'>// 如果缓冲区处于内存1M 以上的地方,则将DMA 缓冲区设在临时缓冲区域(tmp_floppy_area 数组)</font></i>
<a name='L259'><i><font color='green'>// (因为8237A 芯片只能在1M 地址范围内寻址)。如果是写盘命令,则还需将数据复制到该临时区域。</font></i>
<a name='L260'> <b>if</b> (addr >= 0x100000)
<a name='L261'> <font color='red'>{</font>
<a name='L262'> addr = (<b>long</b>) tmp_floppy_area;
<a name='L263'> <b>if</b> (command == FD_WRITE)
<a name='L264'> <a href='../S/55.html#L246' title='Defined at 246 in kernel/blk_drv/floppy.c.'>copy_buffer</a> (<a href='../S/54.html#L116' title='Defined at 116 in kernel/blk_drv/blk.h.'>CURRENT</a>->buffer, tmp_floppy_area);
<a name='L265'> <font color='red'>}</font>
<a name='L266'><i><font color='green'>/* mask DMA 2 */</font></i><i><font color='green'>/* 屏蔽DMA 通道2 */</font></i>
<a name='L267'><i><font color='green'>// 单通道屏蔽寄存器端口为0x10。位0-1 指定DMA 通道(0--3),位2:1 表示屏蔽,0 表示允许请求。</font></i>
<a name='L268'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (4 | 2, 10);
<a name='L269'> <i><font color='green'>/* output command byte. I don't know why, but everyone (minix, */</font></i>
<a name='L270'> <i><font color='green'>/* sanches & canton) output this twice, first to 12 then to 11 */</font></i>
<a name='L271'><i><font color='green'>/* 输出命令字节。我是不知道为什么,但是每个人(minix,*/</font></i>
<a name='L272'><i><font color='green'>/* sanches 和canton)都输出两次,首先是12 口,然后是11 口 */</font></i>
<a name='L273'><i><font color='green'>// 下面嵌入汇编代码向DMA 控制器端口12 和11 写方式字(读盘0x46,写盘0x4A)。</font></i>
<a name='L274'> <b>__asm__</b> ("outb %%al,$12\n\tjmp 1f\n1:\tjmp 1f\n1:\t"
<a name='L275'> "outb %%al,$11\n\tjmp 1f\n1:\tjmp 1f\n1:"::
<a name='L276'> "a" ((<b>char</b>) ((command == FD_READ) ? DMA_READ : DMA_WRITE)));
<a name='L277'><i><font color='green'>/* 8 low bits of addr */</font></i><i><font color='green'>/* 地址低0-7 位 */</font></i>
<a name='L278'><i><font color='green'>// 向DMA 通道2 写入基/当前地址寄存器(端口4)。</font></i>
<a name='L279'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (addr, 4);
<a name='L280'> addr >>= 8;
<a name='L281'><i><font color='green'>/* bits 8-15 of addr */</font></i><i><font color='green'>/* 地址高8-15 位 */</font></i>
<a name='L282'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (addr, 4);
<a name='L283'> addr >>= 8;
<a name='L284'><i><font color='green'>/* bits 16-19 of addr */</font></i><i><font color='green'>/* 地址16-19 位 */</font></i>
<a name='L285'><i><font color='green'>// DMA 只可以在1M 内存空间内寻址,其高16-19 位地址需放入页面寄存器(端口0x81)。</font></i>
<a name='L286'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (addr, 0x81);
<a name='L287'><i><font color='green'>/* low 8 bits of count-1 (1024-1=0x3ff) */</font></i><i><font color='green'>/* 计数器低8 位(1024-1=0x3ff) */</font></i>
<a name='L288'><i><font color='green'>// 向DMA 通道2 写入基/当前字节计数器值(端口5)。</font></i>
<a name='L289'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (0xff, 5);
<a name='L290'><i><font color='green'>/* high 8 bits of count-1 */</font></i><i><font color='green'>/* 计数器高8 位 */</font></i>
<a name='L291'><i><font color='green'>// 一次共传输1024 字节(两个扇区)。</font></i>
<a name='L292'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (3, 5);
<a name='L293'><i><font color='green'>/* activate DMA 2 */</font></i><i><font color='green'>/* 开启DMA 通道2 的请求 */</font></i>
<a name='L294'><i><font color='green'>// 复位对DMA 通道2 的屏蔽,开放DMA2 请求DREQ 信号。</font></i>
<a name='L295'> <a href='../S/55.html#L69' title='Defined at 69 in kernel/blk_drv/floppy.c.'>immoutb_p</a> (0 | 2, 10);
<a name='L296'> <a href='../S/25.html#L14' title='Defined at 14 in include/asm/system.h.'>sti</a> ();
<a name='L297'><font color='red'>}</font>
<a name='L298'>
<a name='L299'><i><font color='green'>//// 向软盘控制器输出一个字节数据(命令或参数)。</font></i>
<a name='L300'><b>static</b> <b>void</b>
<a name='L301'><a href='../R/546.html' title='Multiple refered from 26 places.'>output_byte</a> (<b>char</b> byte)
<a name='L302'><font color='red'>{</font>
<a name='L303'> <b>int</b> counter;
<a name='L304'> <b>unsigned</b> <b>char</b> status;
<a name='L305'>
<a name='L306'> <b>if</b> (reset)
<a name='L307'> <b>return</b>;
<a name='L308'><i><font color='green'>// 循环读取主状态控制器FD_STATUS(0x3f4)的状态。如果状态是STATUS_READY 并且STATUS_DIR=0</font></i>
<a name='L309'><i><font color='green'>// (CPU??FDC),则向数据端口输出指定字节。</font></i>
<a name='L310'> <b>for</b> (counter = 0; counter < 10000; counter++)
<a name='L311'> <font color='red'>{</font>
<a name='L312'> status = <a href='../S/22.html#L25' title='Defined at 25 in include/asm/io.h.'>inb_p</a> (FD_STATUS) & (STATUS_READY | STATUS_DIR);
<a name='L313'> <b>if</b> (status == STATUS_READY)
<a name='L314'> <font color='red'>{</font>
<a name='L315'> <a href='../S/22.html#L3' title='Defined at 3 in include/asm/io.h.'>outb</a> (byte, FD_DATA);
<a name='L316'> <b>return</b>;
<a name='L317'> <font color='red'>}</font>
<a name='L318'> <font color='red'>}</font>
<a name='L319'><i><font color='green'>// 如果到循环1 万次结束还不能发送,则置复位标志,并打印出错信息。</font></i>
<a name='L320'> reset = 1;
<a name='L321'> <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("Unable to send byte to FDC\n\r");
<a name='L322'><font color='red'>}</font>
<a name='L323'>
<a name='L324'><i><font color='green'>//// 读取FDC 执行的结果信息。</font></i>
<a name='L325'><i><font color='green'>// 结果信息最多7 个字节,存放在reply_buffer[]中。返回读入的结果字节数,若返回值=-1</font></i>
<a name='L326'><i><font color='green'>// 表示出错。</font></i>
<a name='L327'><b>static</b> <b>int</b>
<a name='L328'><a href='../R/577.html' title='Multiple refered from 5 places.'>result</a> (<b>void</b>)
<a name='L329'><font color='red'>{</font>
<a name='L330'> <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0, counter, status;
<a name='L331'>
<a name='L332'> <b>if</b> (reset)
<a name='L333'> <b>return</b> -1;
<a name='L334'> <b>for</b> (counter = 0; counter < 10000; counter++)
<a name='L335'> <font color='red'>{</font>
<a name='L336'> status = <a href='../S/22.html#L25' title='Defined at 25 in include/asm/io.h.'>inb_p</a> (FD_STATUS) & (STATUS_DIR | STATUS_READY | STATUS_BUSY);
<a name='L337'> <b>if</b> (status == STATUS_READY)
<a name='L338'> <b>return</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L339'> <b>if</b> (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
<a name='L340'> <font color='red'>{</font>
<a name='L341'> <b>if</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> >= <a href='../S/55.html#L90' title='Defined at 90 in kernel/blk_drv/floppy.c.'>MAX_REPLIES</a>)
<a name='L342'> <b>break</b>;
<a name='L343'> reply_buffer[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++] = <a href='../S/22.html#L25' title='Defined at 25 in include/asm/io.h.'>inb_p</a> (FD_DATA);
<a name='L344'> <font color='red'>}</font>
<a name='L345'> <font color='red'>}</font>
<a name='L346'> reset = 1;
<a name='L347'> <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("Getstatus times out\n\r");
<a name='L348'> <b>return</b> -1;
<a name='L349'><font color='red'>}</font>
<a name='L350'>
<a name='L351'><i><font color='green'>//// 软盘操作出错中断调用函数。由软驱中断处理程序调用。</font></i>
<a name='L352'><b>static</b> <b>void</b>
<a name='L353'><a href='../R/384.html' title='Multiple refered from 2 places.'>bad_flp_intr</a> (<b>void</b>)
<a name='L354'><font color='red'>{</font>
<a name='L355'> <a href='../S/54.html#L116' title='Defined at 116 in kernel/blk_drv/blk.h.'>CURRENT</a>->errors++; <i><font color='green'>// 当前请求项出错次数增1。</font></i>
<a name='L356'><i><font color='green'>// 如果当前请求项出错次数大于最大允许出错次数,则取消选定当前软驱,并结束该请求项(不更新)。</font></i>
<a name='L357'> <b>if</b> (<a href='../S/54.html#L116' title='Defined at 116 in kernel/blk_drv/blk.h.'>CURRENT</a>->errors > <a href='../D/230.html' title='Multiple defined in 2 places.'>MAX_ERRORS</a>)
<a name='L358'> <font color='red'>{</font>
<a name='L359'> <a href='../S/55.html#L202' title='Defined at 202 in kernel/blk_drv/floppy.c.'>floppy_deselect</a> (current_drive);
<a name='L360'> <a href='../S/54.html#L136' title='Defined at 136 in kernel/blk_drv/blk.h.'>end_request</a> (0);
<a name='L361'> <font color='red'>}</font>
<a name='L362'><i><font color='green'>// 如果当前请求项出错次数大于最大允许出错次数的一半,则置复位标志,需对软驱进行复位操作,</font></i>
<a name='L363'><i><font color='green'>// 然后再试。否则软驱需重新校正一下,再试。</font></i>
<a name='L364'> <b>if</b> (<a href='../S/54.html#L116' title='Defined at 116 in kernel/blk_drv/blk.h.'>CURRENT</a>->errors > <a href='../D/230.html' title='Multiple defined in 2 places.'>MAX_ERRORS</a> / 2)
<a name='L365'> reset = 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?