floppy.c ( File view )

  • By 2010-08-31
  • View(s):24
  • Download(s):2
  • Point(s): 1
			/*
* linux/kernel/floppy.c
*
* (C) 1991 Linus Torvalds
*/

/*
* 02.12.91 - Changed to static variables to indicate need for reset
* and recalibrate. This makes some things easier (output_byte reset
* checking etc), and means less interrupt jumping in case of errors,
* so the code is hopefully easier to understand.
*/
/*
* 02.12.91 - 修改成静态变量,以适应复位和重新校正操作。这使得某些事情
* 做起来较为方便(output_byte 复位检查等),并且意味着在出错时中断跳转
* 要少一些,所以希望代码能更容易被理解。
*/

/*
* This file is certainly a mess. I've tried my best to get it working,
* but I don't like programming floppies, and I have only one anyway.
* Urgel. I should check for more errors, and do more graceful error
* recovery. Seems there are problems with several drives. I've tried to
* correct them. No promises.
*/
/*
* 这个文件当然比较混乱。我已经尽我所能使其能够工作,但我不喜欢软驱编程,
* 而且我也只有一个软驱。另外,我应该做更多的查错工作,以及改正更多的错误。
* 对于某些软盘驱动器好象还存在一些问题。我已经尝试着进行纠正了,但不能保证
* 问题已消失。
*/

/*
* As with hd.c, all routines within this file can (and will) be called
* by interrupts, so extreme caution is needed. A hardware interrupt
* handler may not sleep, or a kernel panic will happen. Thus I cannot
* call "floppy-on" directly, but have to set a special timer interrupt
* etc.
*
* Also, I'm not certain this works on more than 1 floppy. Bugs may
* abund.
*/
/*
* 如同hd.c 文件一样,该文件中的所有子程序都能够被中断调用,所以需要特别
* 地小心。硬件中断处理程序是不能睡眠的,否则内核就会傻掉(死机)?。因此不能
* 直接调用"floppy-on",而只能设置一个特殊的时间中断等。
*
* 另外,我不能保证该程序能在多于1 个软驱的系统上工作,有可能存在错误。
*/

#include <linux/sched.h>	// 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,
// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。
#include <linux/fs.h>		// 文件系统头文件。定义文件表结构(file,buffer_head,m_inode 等)。
#include <linux/kernel.h>	// 内核头文件。含有一些内核常用函数的原形定义。
#include <linux/fdreg.h>	// 软驱头文件。含有软盘控制器参数的一些定义。
#include <asm/system.h>		// 系统头文件。定义了设置或修改描述符/中断门等的嵌入式汇编宏。
#include <asm/io.h>		// io 头文件。定义硬件端口输入/输出宏汇编语句。
#include <asm/segment.h>	// 段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。

#define MAJOR_NR 2		// 软驱的主设备号是2。
#include "blk.h"		// 块设备头文件。定义请求数据结构、块设备数据结构和宏函数等信息。

static int recalibrate = 0;	// 标志:需要重新校正。
static int reset = 0;		// 标志:需要进行复位操作。
static int seek = 0;		// 寻道。

extern unsigned char current_DOR;	// 当前数字输出寄存器(Digital Output Register)。

#define immoutb_p(val,port) \	// 字节直接输出(嵌入汇编语言宏)。
__asm__ ("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),
	 "i" (port))
// 这两个定义用于计算软驱的设备号。次设备号 = TYPE*4 + DRIVE。计算方法参见列表后。
#define TYPE(x) ((x)>>2)	// 软驱类型(2--1.2Mb,7--1.44Mb)。
#define DRIVE(x) ((x)&0x03)	// 软驱序号(0--3 对应A--D)。
/*
* Note that MAX_ERRORS=8 doesn't imply that we retry every bad read
* max 8 times - some types of errors increase the errorcount by 2,
* so we might actually retry only 5-6 times before giving up.
*/
/*
* 注意,下面定义MAX_ERRORS=8 并不表示对每次读错误尝试最多8 次 - 有些类型
* 的错误将把出错计数值乘2,所以我们实际上在放弃操作之前只需尝试5-6 遍即可。
*/
#define MAX_ERRORS 8
/*
* globals used by 'result()'
*/
/* 下面是函数'result()'使用的全局变量 */
// 这些状态字节中各比特位的含义请参见include/linux/fdreg.h 头文件。
#define MAX_REPLIES 7		// FDC 最多返回7 字节的结果信息。
     static unsigned char reply_buffer[MAX_REPLIES];	// 存放FDC 返回的结果信息。
#define ST0 (reply_buffer[0])	// 返回结果状态字节0。
#define ST1 (reply_buffer[1])	// 返回结果状态字节1。
#define ST2 (reply_buffer[2])	// 返回结果状态字节2。
#define ST3 (reply_buffer[3])	// 返回结果状态字节3。

/*
* This struct defines the different floppy types. Unlike minix
* linux doesn't have a "search for right type"-type, as the code
* for that is convoluted and weird. I've got enough problems with
* this driver as it is.
*
* The 'stretch' tells if the tracks need to be boubled for some
* types (ie 360kB diskette in 1.2MB drive etc). Others should
* be self-explanatory.
*/
/*
* 下面的软盘结构定义了不同的软盘类型。与minix 不同的是,linux 没有
* "搜索正确的类型"-类型,因为对其处理的代码令人费解且怪怪的。本程序
* 已经让我遇到了许多的问题了。
*
* 对某些类型的软盘(例如在1.2MB 驱动器中的360kB 软盘等),'stretch'用于
* 检测磁道是否需要特殊处理。其它参数应该是自明的。
*/
// 软盘参数有:
// size 大小(扇区数);
// sect 每磁道扇区数;
// head 磁头数;
// track 磁道数;
// stretch 对磁道是否要特殊处理(标志);
// gap 扇区间隙长度(字节数);
// rate 数据传输速率;
// spec1 参数(高4 位步进速率,低四位磁头卸载时间)。
     static struct floppy_struct
     {

       unsigned int size, sect, head, track, stretch;
       unsigned char gap, rate, spec1;
     
}
floppy_type[] =
{

  {

  0, 0, 0, 0, 0, 0x00, 0x00, 0x00
}
  ,				/* no testing */
  {

  720, 9, 2, 40, 0, 0x2A, 0x02, 0xDF
}
  ,				/* 360kB PC diskettes */
  {

  2400, 15, 2, 80, 0, 0x1B, 0x00, 0xDF
}
  ,				/* 1.2 MB AT-diskettes */
  {

  720, 9, 2, 40, 1, 0x2A, 0x02, 0xDF
}
  ,				/* 360kB in 720kB drive */
  {

  1440, 9, 2, 80, 0, 0x2A, 0x02, 0xDF
}
  ,				/* 3.5" 720kB diskette */
  {

  720, 9, 2, 40, 1, 0x23, 0x01, 0xDF
}
  ,				/* 360kB in 1.2MB drive */
  {

  1440, 9, 2, 80, 0, 0x23, 0x01, 0xDF
}
  ,				/* 720kB in 1.2MB drive */
  {

  2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF
}
  ,				/* 1.44MB diskette */

};

/*
* Rate is 0 for 500kb/s, 2 for 300kbps, 1 for 250kbps
* Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),
* H is head unload time (1=16ms, 2=32ms, etc)
*
 * Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms etc)
 * and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
 */
/*
* 上面速率rate:0 表示500kb/s,1 表示300kbps,2 表示250kbps。
* 参数spec1 是0xSH,其中S 是步进速率(F-1 毫秒,E-2ms,D=3ms 等),
* H 是磁头卸载时间(1=16ms,2=32ms 等)
*
* spec2 是(HLD<<1 | ND),其中HLD 是磁头加载时间(1=2ms,2=4ms 等)
* ND 置位表示不使用DMA(No DMA),在程序中硬编码成6(HLD=6ms,使用DMA)。
*/

extern void floppy_interrupt (void);
extern char tmp_floppy_area[1024];

 /*
    * These are global variables, as that's the easiest way to give
    * information to interrupts. They are the data used for the current
    * request.
  */
/*
* 下面是一些全局变量,因为这是将信息传给中断程序最简单的方式。它们是
* 用于当前请求的数据。
*/
static int cur_spec1 = -1;
static int cur_rate = -1;
static struct floppy_struct *floppy = floppy_type;
static unsigned char current_drive = 0;
static unsigned char sector = 0;
static unsigned char head = 0;
static unsigned char track = 0;
static unsigned char seek_track = 0;
static unsigned char current_track = 255;
static unsigned char command = 0;
unsigned char selected = 0;
struct task_struct *wait_on_floppy_select = NULL;

//// 释放(取消选定的)软盘(软驱)。
// 数字输出寄存器(DOR)的低2 位用于指定选择的软驱(0-3 对应A-D)。
void
floppy_deselect (unsigned int nr)
{

  if (nr != (current_DOR & 3))
    printk ("floppy_deselect: drive not selected\n\r");
  selected = 0;
  wake_up (&wait_on_floppy_select);

}

 /*
    * floppy-change is never called from an interrupt, so we can relax a bit
    * here, sleep etc. Note that floppy-on tries to set current_DOR to point
    * to the desired drive, but it will probably not survive the sleep if
    * several floppies are used at the same time: thus the loop.
  */
/*
* floppy-change()不是从中断程序中调用的,所以这里我们可以轻松一下,睡觉等。
* 注意floppy-on()会尝试设置current_DOR 指向所需的驱动器,但当同时使用几个
* 软盘时不能睡眠:因此此时只能使用循环方式。
*/
//// 检测指定软驱中软盘更换情况。如果软盘更换了则返回1,否则返回0。
int
floppy_change (unsigned int nr)
{

repeat:
  floppy_on (nr);		// 开启指定软驱nr(kernel/sched.c,251)。
// 如果当前选择的软驱不是指定的软驱nr,并且已经选择其它了软驱,则让当前任务进入可中断
// 等待状态。
  while ((current_DOR & 3) != nr && selected)
    interruptible_sleep_on (&wait_on_floppy_select);
// 如果当前没有选择其它软驱或者当前任务被唤醒时,当前软驱仍然不是指定的软驱nr,则循环等待。
  if ((current_DOR & 3) != nr)
    goto repeat;
// 取数字输入寄存器值,如果最高位(位7)置位,则表示软盘已更换,此时关闭马达并退出返回1。
// 否则关闭马达退出返回0。
  if (inb (FD_DIR) & 0x80)
    {

      floppy_off (nr);
      return 1;
    
}
  floppy_off (nr);
  return 0;

}

//// 复制内存块。
#define copy_buffer(from,to) \
 __asm__( "cld ; rep ; movsl" \
 :: "c" (BLOCK_SIZE/4), "S" ((long)(from)), "D" ((long)(to)) \
 : "cx", "di", "si")

//// 设置(初始化)软盘DMA 通道。
static void
setup_DMA (void)
{

  long addr = (long) CURRENT->buffer;	// 当前
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 1

Download
0 lines left, continue to read
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
linux0.00 B0% 04-10-07
<boot>0.00 B04-10-07 15:01
bootsect.s12.49 kB08-01-04 21:38
head.s13.22 kB08-01-04 21:38
setup.s12.42 kB08-01-04 21:38
<fs>0.00 B04-10-07 15:01
bitmap.c8.46 kB02-09-04 13:12
block_dev.c3.95 kB02-09-04 13:12
buffer.c17.71 kB02-09-04 13:12
char_dev.c4.09 kB02-09-04 13:12
exec.c18.90 kB02-09-04 13:12
fcntl.c3.33 kB02-09-04 13:12
file_dev.c4.82 kB02-09-04 13:12
file_table.c209.00 B02-09-04 13:12
inode.c14.92 kB02-09-04 13:12
ioctl.c1.94 kB02-09-04 13:12
Makefile6.80 kB08-01-04 21:45
namei.c37.20 kB02-09-04 13:12
open.c10.00 kB02-09-04 13:12
pipe.c5.42 kB02-09-04 13:12
read_write.c5.86 kB02-09-04 13:12
stat.c2.69 kB02-09-04 13:12
super.c13.57 kB02-09-04 13:12
truncate.c2.46 kB02-09-04 13:12
<include>0.00 B04-10-07 15:01
a.out.h8.22 kB02-09-04 13:14
<asm>0.00 B04-10-07 15:01
io.h772.00 B02-09-04 13:14
memory.h1.03 kB08-01-04 22:13
segment.h2.50 kB02-09-04 13:14
system.h4.08 kB02-09-04 13:14
const.h589.00 B02-09-04 13:14
ctype.h1.68 kB02-09-04 13:14
errno.h2.30 kB02-09-04 13:14
fcntl.h3.30 kB02-09-04 13:14
<linux>0.00 B04-10-07 15:01
config.h2.16 kB02-09-04 13:14
fs.h9.72 kB02-09-04 13:14
hdreg.h2.94 kB02-09-04 13:14
head.h760.00 B02-09-04 13:14
kernel.h1.44 kB02-09-04 13:14
mm.h473.00 B02-09-04 13:14
sched.h13.25 kB02-09-04 13:14
sys.h5.41 kB02-09-04 13:14
tty.h3.93 kB02-09-04 13:14
signal.h4.01 kB02-09-04 13:14
stdarg.h1.77 kB02-09-04 13:14
stddef.h378.00 B02-09-04 13:14
string.h21.75 kB02-09-04 13:14
<sys>0.00 B04-10-07 15:01
stat.h2.37 kB02-09-04 13:14
times.h377.00 B02-09-04 13:14
types.h1.10 kB02-09-04 13:14
utsname.h423.00 B02-09-04 13:14
wait.h1.48 kB02-09-04 13:14
termios.h13.58 kB02-09-04 13:14
time.h1.81 kB02-09-04 13:14
unistd.h9.21 kB02-09-04 13:14
utime.h392.00 B02-09-04 13:14
<init>0.00 B04-10-07 15:01
main.c12.52 kB02-09-04 13:12
<kernel>0.00 B04-10-07 15:01
asm.s5.10 kB08-01-04 22:48
<blk_drv>0.00 B04-10-07 15:01
blk.h5.69 kB02-09-04 13:14
floppy.c23.49 kB02-09-04 13:12
hd.c17.14 kB02-09-04 13:12
ll_rw_blk.c7.59 kB02-09-04 13:12
Makefile4.25 kB08-01-04 22:53
ramdisk.c6.13 kB02-09-04 13:12
<chr_drv>0.00 B04-10-07 15:01
console.c30.91 kB02-09-04 13:12
keyboard.S21.04 kB08-01-04 22:59
Makefile4.81 kB08-01-04 22:59
rs_io.s5.75 kB08-01-04 22:59
serial.c2.91 kB02-09-04 13:12
tty_io.c18.40 kB02-09-04 13:12
tty_ioctl.c10.70 kB02-09-04 13:12
exit.c8.08 kB02-09-04 13:12
fork.c6.78 kB15-07-07 22:10
<math>0.00 B04-10-07 15:01
Makefile3.21 kB08-01-04 23:01
math_emulate.c2.08 kB02-09-04 13:12
mktime.c2.72 kB02-09-04 13:12
panic.c952.00 B02-09-04 13:12
printk.c1.75 kB02-09-04 13:12
sched.c18.57 kB16-07-07 21:23
signal.c5.61 kB02-09-04 13:12
sys.c7.62 kB02-09-04 13:12
system_call.s12.53 kB08-01-04 22:48
traps.c8.29 kB04-10-07 14:57
vsprintf.c9.96 kB02-09-04 13:12
<lib>0.00 B04-10-07 15:01
close.c397.00 B02-09-04 13:12
ctype.c1.72 kB02-09-04 13:12
dup.c401.00 B02-09-04 13:12
errno.c66.00 B02-09-04 13:12
execve.c607.00 B02-09-04 13:12
Makefile4.83 kB08-01-04 22:30
malloc.c13.50 kB02-09-04 13:12
open.c1.22 kB02-09-04 13:12
setsid.c382.00 B02-09-04 13:12
string.c199.00 B02-09-04 13:12
wait.c774.00 B02-09-04 13:12
write.c545.00 B02-09-04 13:12
_exit.c616.00 B02-09-04 13:12
Makefile8.58 kB08-01-04 22:21
<mm>0.00 B04-10-07 15:01
Makefile2.91 kB08-01-04 22:34
memory.c25.10 kB02-09-04 13:12
page.s842.00 B08-01-04 22:34
<tools>0.00 B04-10-07 15:01
build.c8.12 kB02-09-04 13:12
...
Sponsored links

floppy.c (286.77 kB)

Need 1 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D