/*/*
* linux/kernel/hd.c
*
* (C) 1991 Linus Torvalds
*/
/*
* This is the low-level hd interrupt support. It traverses the
* request-list, using interrupts to jump between functions. As
* all the functions are called within interrupts, we may not
* sleep. Special care is recommended.
*
* modified by Drew Eckhardt to check nr of hd's from the CMOS.
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/hdreg.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/segment.h>
#define MAJOR_NR 3
#include "blk.h"
#define CMOS_READ(addr) ({ / //--读CMOS中硬盘信息
outb_p(0x80|addr,0x70); /
inb_p(0x71); /
})
/* Max read/write errors/sector */
#define MAX_ERRORS 7
#define MAX_HD 2
static void recal_intr(void);
static void bad_rw_intr(void);
static int recalibrate = 0;
static int reset = 0;
/*
* This struct defines the HD's and their types.
*/
struct hd_i_struct { //--定义硬盘参数及类型
int head,sect,cyl,wpcom,lzone,ctl;
};
#ifdef HD_TYPE
struct hd_i_struct hd_info[] = { HD_TYPE };
#define NR_HD ((sizeof (hd_info))/(sizeof (struct hd_i_struct)))
#else
struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
static int NR_HD = 0;
#endif
static struct hd_struct {
long start_sect;
long nr_sects;
} hd[5*MAX_HD]={
{0,0},};
static int hd_sizes[5*MAX_HD] = {0, };
#define port_read(port,buf,nr) / //--读端口嵌入汇编宏
__asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr):"cx","di")
#define port_write(port,buf,nr) / //--写端口嵌入汇编宏
__asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr):"cx","si")
extern void hd_interrupt(void); //--硬盘中断过程
extern void rd_load(void); //--虚拟盘创建加载函数
/* This may be used only once, enforced by 'static int callable' */
int sys_setup(void * BIOS) //--系统设置函数,只在初始化时被调用一次
{ //--BIOS为指向硬盘参数表结构的指针
static int callable = 1;
int i,drive;
unsigned char cmos_disks;
struct partition *p;
struct buffer_head * bh;
if (!callable) //--只调用一次
return -1;
callable = 0;
#ifndef HD_TYPE
for (drive=0 ; drive<2 ; drive