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

unsigned short        bi_vcnt;    /* how many bio_vec's (bio_vec的数量)*/
        unsigned short        bi_idx;        /* current index into bvl_vec(当前bio_vec的索引) */

/*不相邻的物理段的数目*/
        unsigned short        bi_phys_segments;
       
        /*物理合并和DMA remap合并后不相邻的物理扇区*/   
        unsigned short        bi_hw_segments;

/*被传送的数据大小(byte),用bio_sector(bio)获取扇区为单位的大小*/
        unsigned int        bi_size;    /* residual I/O count */

/*被传送的数据大小(byte),用bio_sector(bio)获取扇区为单位的大小*/
        /*为了明了最大的hw尺寸,考虑bio中第一个和最后一个虚拟的可合并的段的尺寸*/
        unsigned int        bi_hw_front_size;
        unsigned int        bi_hw_back_size;

unsigned int        bi_max_vecs;    /*能持有的最大bvl_vecs数*/

struct bio_vec        *bi_io_vec;    /*能持有的最大bvl_vecs数*/
        ...................
    }
   
   
    struct bio_vec {
    struct page        *bv_page; /*要操作的页指针*/
    unsigned int    bv_len;      /*要传输的字节数*/
    unsigned int    bv_offset;/*偏移位置*/
    };
   
    /*一般不直接访问bio的bio_vec成员,而使用bio_for_each_segment()宏进行操作.
    *该宏循环遍历整个bio中的每个段.
    */
    #define __bio_for_each_segment(bvl, bio, i, start_idx)\
            for(
                bvl = bio_iovec_idx((bio),(start_idx)),i = (start_idx);\
                i <(bio)->bi_vcnt;\
                bvl++, i++\
            )
    #define bio_for_each_segment(bvl, bio, i)\
              __bio_for_each_segment(bvl, bio, i, (bio)->bi_idx)
   
    在内核中,提供了一组函数(宏)用于操作bio:
    int bio_data_dir(struct bio* bio);
   
    该函数用于获得数据传送方向.
    struct page* bio_page(struct bio* bio);
   
    该函数用于获得目前的页指针.
    int bio_offset(struct bio* bio);
   
    该函数返回操作对应的当前页的页内偏移,通常块IO操作本身就是页对齐的.
    int bio_cur_sectors(struct bio* bio);
   
    该函数返回当前bio_vec要传输的扇区数.
    char* bio_data(struct bio* bio);
   
    该函数返回数据缓冲区的内核虚拟地址.
    char* bvec_kmap_irq(struct bio_vec* bvec, unsigned long* offset);
    该函数也返回一个内核虚拟地址此地址可用于存取被给定的bio_vec入口指向的数据缓冲区.同时会屏蔽中断并返回一个原子kmap,因此,在此函数调用之前,驱动不应该是睡眠状态.
    void bvec_kunmap_irq(char* buffer, unsigned long flags);
   
    该函数撤销函数bvec_kmap_irq()创建的内存映射.
    char* bio_kmap_irq(struct bio* bio, unsigned long* flags);
   
    该函数是对bvec_kmap_irq函数的封装,它返回给定的比偶的当前bio_vec入口的映射.
    char* __bio_kmap_atomic(struct bio* bio, int i, enum km_type type);
   
    该函数是通过kmap_atomic()获得返回给定bio的第i个缓冲区的虚拟地址.
    void __bio_kunmap_atomic(char* addr, enum km_type type);
   
    该函数返还由函数__bio_kmap_atomic()获得的内核虚拟地址给系统.
    void bio_get(struct bio* bio);
    void bio_put(struct bio* bio);
7、块设备注册与取消

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

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