Linux驱动开发之块设备初入门(3)

struct request_queue
    {
        ..........................
        /*自旋锁 保护队列结构*/
        spinlock_t        __queue_lock;
        spinlock_t        *queue_lock;

/*kobject队列 */
        struct kobject kobj;

/* queue settings */
        unsigned long nr_requests;        /*最大的请求数量*/
        unsigned int  nr_congestion_on;
        unsigned int  nr_congestion_off;
        unsigned int  nr_batching;
        unsigned short max_sectors;        /*最大扇区数*/
        unsigned short max_hw_sectors;
        unsigned short max_phys_sectors;/*最大的段数*/
        unsigned short max_hw_segments;
        unsigned short hardsect_size;    /*硬件扇区尺寸*/
        unsigned int max_segment_size;    /*最大的段尺寸*/
        unsigned long seg_boundary_mask;/*段边界掩码*/
        unsigned int dma_alignment;        /*DMA传送内存对齐限制*/
        struct blk_queue_tag* queue_tags;
        atomic_t refcnt;                /*引用计数*/
        unsigned int in_flight;
        unsigned int sg_timeout;
        unsigned int sg_reserved_size;
        int node;
        struct list_head drain_list;
        struct request* flush_rq;
        unsigned char ordered;
    };
   
    关于request_queue的操作:
    /*初始化请求队列*/
   
    kernel elevator = deadline;/*给kernel添加启动参数*/
   
    request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
    /*
    *两个参数分别是请求处理函数指针 控制队列访问权限的自旋锁
    *此函数会分配内存,需要判断返回值,在加载函数中调用
    */
   
   
   
    /*清除请求队列*/
    void blk_cleanup_queue(request_queue_t * q)
    /*
    * 此函数完成将请求队列返回给系统的任务,一般在卸载函数中调用.
    * 此函数即bld_put_queue()的宏定义#define blk_put_queue(q) blk_cleanup_queue((q))
    */
   
   
   
    /*分配请求队列*/
    request_queue_t *blk_alloc_queue(gfp_t gfp_mask)
   
    void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
    /*
    * 前一个函数用于分配一个请求队列,后一个函数是将请求队列和"制造函数"进行绑定
    * 但函数blk_alloc_queue实际上并不包含任何请求.
    */
   
    /*去除请求*/
    void blkdev_dequeue_request(struct request* req);
    void elv_requeue_request(request_queue_t* queue, struct request* req);
   
    /*启停请求*/
    void blk_stop_queue(request_queue_t* queue);
    void blk_start_queue(request_queue_t* queue);
   
    //参数设置
    void blk_queue_max_sectors(request_queue_t* q, unsigned short max);
    /*请求可包含的最大扇区数.默认255*/
   
    void blk_queue_max_phys_segments(request_queue_t* q, unsigned short max);
    void blk_queue_max_hw_segments(request_queue_t* q, unsigned short max);
    /*这两个函数设置一个请求可包含的最大物理段数(系统内存中不相邻的区),缺省是128*/
   
   
    void blk_queue_max_segment_size(request_queue_t* q, unsigned int max);
    /*告知内核请求短的最大字节数,默认2^16 = 65536*/
   
    //通告内核
    void blk_queue_bounce_limit(request_queue_t* queue, u64 dma_addr);
    /*
    * 此函数告知内核设备执行DMA时,可使用的最高物理地址dma_addr,常用的宏如下:
    * BLK_BOUNCE_HIGH:对高端内存页使用反弹缓冲(缺省)
    * BLK_BOUNCE_ISA:驱动只可以在MB的ISA区执行DMA
    * BLK_BOUNCE_ANY:驱动可在任何地方执行DMA
    */   
   
    blk_queue_segment_boundary(request_queue_t* queue, unsigned long mask);
    /*这个函数在设备无法处理跨越一个特殊大小内存边界的请求时,告知内核这个边界.*/
   
    void blk_queue_dma_alignment(request_queue_t* q, int mask);
    /*告知内核设备加于DMA传送的内存对齐限制*/
   
    viod blk_queue_hardsect_size(request_queue_t* q, unsigned short max);
    /*此函数告知内核块设备硬件扇区大小*/
   
   
    块IO(bio)结构体:
        通常一个bio对应一个IO请求,IO调度算法可以将连续的bio合并成一个请求,所以一个请求包含多个bio
   
    struct bio {
        sector_t        bi_sector;    /* device address in 512 byte  sectors */
        struct bio        *bi_next;    /* request queue link */
        struct block_device    *bi_bdev;
       
        /*如果是一个写请求,最低有效位被置位,可使用bio_data_dir(bio)宏来获取读写方向*/
        unsigned long        bi_flags;    /* status, command, etc */
        unsigned long        bi_rw;        /* 低位代表:READ/WRITE,高位代表:优先级 */

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1113f82fc69a591afa0531884adb3059.html