Chinaunix首页 | 论坛 | 博客
  • 博客访问: 581191
  • 博文数量: 137
  • 博客积分: 4040
  • 博客等级: 上校
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-08 13:05
文章分类

全部博文(137)

文章存档

2011年(10)

2010年(23)

2009年(104)

分类: LINUX

2009-08-06 11:55:26

#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

阅读(1029) | 评论(0) | 转发(0) |
0

上一篇:panic.c

下一篇:ll_wr_blk.c

给主人留下些什么吧!~~