#ifndef _BLK_H #define _BLK_H
#define NR_BLK_DEV 7//块设备数量
/* * NR_REQUEST is the number of entries in the request-queue. * NOTE that writes may use only the low 2/3 of these: reads * take precedence. * * 32 seems to be a reasonable number: enough to get some benefit * from the elevator-mechanism, but not so much as to lock a lot of * buffers when they are in the queue. 64 seems to be too many (easily * long pauses in reading when heavy writing/syncing is going on) */ #define NR_REQUEST 32//块请求队列中所包含的项数,写操作用这些项的底2/3项,且读操作优先处理
/* * Ok, this is an expanded form so that we can use the same * request for paging requests when that is implemented. In * paging, 'bh' is NULL, and 'waiting' is used to wait for * read/write completion. */ struct request { int dev; /* -1 if no request *///使用的设备号,当为-1时表示该项没有被使用,0无无,1块ram, 2块fd软盘,3块hd硬盘,4字符ttyx终端,5字符tty设备,6字符lp打印机设备
int cmd; /* READ or WRITE *///命令read 或write
int errors;//操作时产生的错误次数
unsigned long sector;//起始扇区 (1块==2扇区)
unsigned long nr_sectors;//读写扇区数
char * buffer;//数据缓冲区
struct task_struct * waiting;//等待该请求项的进程,(任务等待操作执行完成的地方)
struct buffer_head * bh;//缓冲区头指针
struct request * next;//指向下一个请求项
};
/* * This is used in the elevator algorithm: Note that * reads always go before writes. This is natural: reads * are much more time-critical than writes. */ #define IN_ORDER(s1,s2) \ ((s1)->cmd<(s2)->cmd || (s1)->cmd==(s2)->cmd && \ ((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \ (s1)->sector < (s2)->sector)))//定义用于电梯算法,s1 s2 为request结构,来判断出两个请求项结构的前后排列顺序
struct blk_dev_struct { void (*request_fn)(void);//请求项操作的函数指针,用于操作相应块设备的请求项,对于硬盘驱动程序为do_hd_request,对于软盘驱动程序则为do_floppy_request().
struct request * current_request;//当前请求项指针,用于表明块设备目前正在处理的请求项,初始化时被置为空
};
extern struct blk_dev_struct blk_dev[NR_BLK_DEV];//块设备表数组,每种块设备占用一项
extern struct request request[NR_REQUEST];//请求项数组
extern struct task_struct * wait_for_request;//等待空闲请求项的 进程队列头指针
#ifdef MAJOR_NR//主设备号,ram 为1 , fd 为2 ,hd为3
/* * Add entries as needed. Currently the only block devices * supported are hard-disks and floppies. */
#if (MAJOR_NR == 1)//ram盘
/* ram disk */ #define DEVICE_NAME "ramdisk"//设备名称
#define DEVICE_REQUEST do_rd_request//设备请求函数
#define DEVICE_NR(device) ((device) & 7)//设备号(0---7)
#define DEVICE_ON(device) //开启设备,虚拟磁盘无需开启关闭
#define DEVICE_OFF(device)//关闭设备
#elif (MAJOR_NR == 2)//软盘
/* floppy */ #define DEVICE_NAME "floppy"//名称
#define DEVICE_INTR do_floppy//中断处理函数
#define DEVICE_REQUEST do_fd_request//请求函数
#define DEVICE_NR(device) ((device) & 3)//设备号(0----3)
#define DEVICE_ON(device) floppy_on(DEVICE_NR(device))//开户
#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))//关闭
#elif (MAJOR_NR == 3)//硬盘
/* harddisk */ #define DEVICE_NAME "harddisk"//名称
#define DEVICE_INTR do_hd//中断处理函数
#define DEVICE_REQUEST do_hd_request//请求函数
#define DEVICE_NR(device) (MINOR(device)/5)//设备号(0----1),每个硬 盘可有4个分区
#define DEVICE_ON(device)//开,硬盘一直在工作,无需开和关
#define DEVICE_OFF(device)//关
#elif /* unknown blk device */ #error "unknown blk device"
#endif
#define CURRENT (blk_dev[MAJOR_NR].current_request)//指定主设备号的当前请求项指针
#define CURRENT_DEV DEVICE_NR(CURRENT->dev)//当前请求项CURRENT的设备号
#ifdef DEVICE_INTR void (*DEVICE_INTR)(void) = NULL;//设备中断处理函数指针,初始时置为空,与前对应
#endif static void (DEVICE_REQUEST)(void);//声明请求函数,无参数无返回的静态函数指针,与对应
extern inline void unlock_buffer(struct buffer_head * bh)//解锁指定的缓冲区
{ if (!bh->b_lock) printk(DEVICE_NAME ": free buffer being unlocked\n"); bh->b_lock=0;//解锁
wake_up(&bh->b_wait);//唤醒
}
extern inline void end_request(int uptodate)//结束请求处理
{ DEVICE_OFF(CURRENT->dev);//关闭设备,CURRENT为当前请求项
if (CURRENT->bh) {//当前请示项的缓冲区头指针为真时,说明此次读写缓冲区有效
CURRENT->bh->b_uptodate = uptodate;//缓冲区置更新标志
unlock_buffer(CURRENT->bh);//解锁缓冲区
} if (!uptodate) {//更新标志为0 ,则显示出错信息
printk(DEVICE_NAME " I/O error\n\r"); printk("dev %04x, block %d\n\r",CURRENT->dev, CURRENT->bh->b_blocknr); } wake_up(&CURRENT->waiting);//唤醒等待该请求项的进程,也就是对应于这个设备(CURRENT->dev(0---6))的其余请求项
wake_up(&wait_for_request);//唤醒等待空闲请求项的进程
CURRENT->dev = -1;//释放该请求项
CURRENT = CURRENT->next;//当前请求项指针指向下一个请求项(同一个设备的其余请求项)
}
#define INIT_REQUEST \//定义初始化请求项宏
repeat: \ if (!CURRENT) \//当前请求项为空,说明本设备目前没有需要处理的请求项,刚返回
return; \ if (MAJOR(CURRENT->dev) != MAJOR_NR) \//当前请求项中设备的主设备号不是我们定义的主设备号,说明请求队列乱了,则死机
panic(DEVICE_NAME ": request list destroyed"); \ if (CURRENT->bh) { \ if (!CURRENT->bh->b_lock) \//如果请求项中的缓冲区没有被锁定,说明内核程序出了问题,则死机
panic(DEVICE_NAME ": block not locked"); \ }
#endif
#endif
|