#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
|