LDD3讀書筆記(第12章 塊裝置驅動程式)

2021-06-09 11:39:13 字數 4852 閱讀 4178

#include

int register_blkdev(unsigned int major,counst char *name);

int unregister_blkdev(unsigned int major,const char *name);

register_blkdev用來向核心註冊乙個塊裝置驅動程式,還可以獲得主裝置號。乙個驅動程式可以使用unregister_blkdev函式登出。

struct block_device_operations

用來儲存塊裝置驅動程式大多數方法的資料結構。

#include

struct gendisk;

用來描述核心中單個塊裝置的結構。

struct gendisk *alloc_disk(int minors);

void add_disk(struct gendisk *gd);

用來分配gendisk結構並將其返回給系統的函式。

void set_capacity(struct gendisk *gd,sector_t sectors);

在gendisk結構中儲存裝置容量(用512位元組扇區單位)。

void add_disk(struct gendisk *gd);

向核心新增乙個磁碟。一旦呼叫了該函式,核心就能呼叫磁碟方法了。

int check_disk_change(struct block_device *bdev);

用來對指定磁碟驅動器進行介質變化檢查的核心函式,當介質改變被偵測到後,採取必要的清除動作。

#include

request_queue_t blk_init_queue(request_fn_proc *request,spinlock_t *lock);

void blk_cleanup_queue(request_queue_t *);

用來建立和刪除塊裝置請求佇列的函式。

struct request *elv_next_request(request_queue_t *queue);

void end_request(struct request *req,int success);

elv_next_quest獲得請求佇列中的下乙個請求;end_request用在簡單的驅動程式中,以完成(或部分完成)乙個請求。

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);

如果不想讓自己的請求函式呼叫,blk_stop_queue可以做到這點。為了能使請求函式被呼叫,必須呼叫blk_start_queue的函式。

void blk_queue_bounce_limit(request_queue_t *queue,u64 dma_addr);

void blk_queue_max_sectors(request_queue_t *queue,unsigned short max);

void blk_queue_max_phys_segments(request_queue_t *queue,unsigned short max);

void blk_queue_max_hw_segments(request_queue_t *queue,unsigend short max);

void blk_queue_max_segment_size(request_queue_t *queue,unsigned int max);

blk_queue_segment_boundary(request_queue_t *queue,unsigned long mask);

void blk_queue_dma_alignment(request_queue_t *queue,int mask);

void blk_queue_hardsect_size(request_queue *queue,unsigned short max);

用來設定佇列引數的函式。這些引數控制了對乙個特定裝置請求的建立。引數的具體解釋在「佇列控制函式」一節。

#include

struct bio;

表示部分塊裝置i/o請求的底層結構。

bio_sectors(struct bio *bio);

bio_data_dir(struct bio *bio);

這兩個巨集用來獲得bio結構描述的大小和傳輸方向。

bio_for_each_segment(bvec,bio,segno);

用來遍歷組成bio結構的段的偽控制結構。

char *__bio_kmap_atomic(struct bio *bio,int i,enum km_type type);

void __bio_kunmap_atomic(char *buffer,enum km_type type);

__bio_kmap_atomic用來為bio結構中指定的段建立核心虛擬位址。取消該對映必須使用__bio_kunmap_atomic。

struct page *bio_page(struct bio *bio);

int bio_offset(struct bio *bio);

int bio_cur_sectors(struct bio *bio);

char *bio_data(struct bio *bio);

char *bio_kmap_irq(struct bio *bio,unsigned long *flags);

void bio_kunmap_irq(char *buffer,unsigned long *flags);

這是一組訪問巨集,用來訪問bio結構中的「當前」段。

void blk_queue_ordered(request_queue_t *queue,int flag);

int blk_barrier_rq(struct request *req);

如果驅動程式實現了屏障請求,則呼叫blk_queue_ordered。如果當前請求是乙個屏障請求,則巨集blk_barrier_rq返回非零值。

int blk_noretry_request(struct request *req);

該巨集返回非零值表示指定的請求因錯誤不能再次被執行。

int end_that_request_first(struct request *irq,int success,int count);

void end_that_request_last(struct request *req);

使用end_that_request_first表示完成乙個塊裝置i/o請求的過程。如果該函式返回0,則表示請求已經完成,應該被傳遞給end_that_request_last。

rq_for_each_bio(bio,request)

另外乙個以巨集的形式實現的控制結構,它將遍歷請求中的每個bio結構。

int blk_rq_map_sg(request_queue_t *queue,struct request *req,struct scatterlist *list);

為dma傳輸,需要將緩衝區對映到指定的request中,使用這些資訊填充分散表。

typedef int(make_request_fn)(request_queue_t *q,struct bio *bio);

make_request函式的原型。

void bio_endio(struct bio *bio,unsigend int bytes,int error);

指定的bio結構的訊號完成函式。只有當驅動程式通過make_request函式直接從塊裝置層獲得bio結構時,才能用該函式。

request_queue_t *blk_alloc_queue(int flags);

void blk_queue_make_request(request_queue_t *queue,make_request_fn *func);

使用blk_alloc_queue來分配乙個請求佇列,以便為使用者定義的make_request函式所使用。該函式要用blk_queue_make_request設定。

typedef int (prep_rq_fn)(request_queue_t *queue,struct request *req);

void blk_queue_prep_rq(request_queue_t *queue,prep_rq_fn *func);

命令預處理函式的原型和設定,它可以在請求傳遞到請求處理函式前,為硬體準備需要的命令。

int blk_queue_inti_tags(request_queue_t *queue,int depth,struct blk_queue_tag *tags);

int blk_queue_resize_tags(request_queue_t *queue,int new_depth);

int blk_queue_start_tag(request_queue_t *queue,struct request *req);

void blk_queue_end_tag(request_queue_t *queue,struct request *req);

struct request *blk_queue_find_tag(request_queue_t *qeue,int tag);

void blk_queue_invalidate_tags(request_queue_t *queue);

為了讓驅動程式使用標記命令佇列而提供的支援函式。

LDD3讀書筆記(第3章 字元驅動)

include dev t dev t 是用來在核心裡代表裝置號的型別.int major dev t dev int minor dev t dev 從裝置編號中抽取主次編號的巨集.dev t mkdev unsigned int major,unsigned int minor 從主次編號來建立...

LDD3讀書筆記(第13章 網路裝置驅動)

這個小節給出了本章介紹過的概念的快速參考,同時解釋了驅動程式應該包含的每個標頭檔案。但是net device和sk buff結構的成員不會在這裡重複。include 這個標頭檔案儲存有net device和net device stats結構的定義,幷包含了網路驅動程式需要的其他幾個標頭檔案。str...

LDD3讀書筆記(第5章 記憶體分配)

include void kmalloc size t size,int flags 記憶體分配函式 後備快取記憶體 include kmem cache t kmem cache create const char name,size t size,size t offset,unsigned l...