W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
本節(jié)涵蓋塊層的幾個(gè)其他的方面, 對(duì)于高級(jí)讀者可能有興趣. 對(duì)于編寫一個(gè)正確的驅(qū)動(dòng)下面的內(nèi)容都不需要, 但是它們?cè)谀承┣闆r下可能是有用的.
塊層為驅(qū)動(dòng)提供一個(gè)進(jìn)制來(lái)檢查和預(yù)處理請(qǐng)求, 在它們被從 elv_next_request 返回前. 這個(gè)機(jī)制允許驅(qū)動(dòng)提前設(shè)立真正的驅(qū)動(dòng)器命令, 決定是否這個(gè)請(qǐng)求可被完全處理, 或者進(jìn)行其他的維護(hù)工作.
如果你想使用這個(gè)特性, 創(chuàng)建一個(gè)命令準(zhǔn)備函數(shù), 它要適應(yīng)這個(gè)原型:
typedef int (prep_rq_fn) (request_queue_t *queue, struct request *req);
請(qǐng)求結(jié)構(gòu)包含一個(gè)成員 cmd, 它是一個(gè) BLK_MAX_CDB 字節(jié)的數(shù)組; 這個(gè)數(shù)組可被這個(gè)準(zhǔn)備函數(shù)用來(lái)存儲(chǔ)實(shí)際的硬件命令(或者任何其他的有用信息). 這個(gè)函數(shù)應(yīng)當(dāng)返回一個(gè)下列的值:
BLKPREP_OK
命令準(zhǔn)備正常進(jìn)行, 并且這個(gè)請(qǐng)求可被傳遞給你的驅(qū)動(dòng)的請(qǐng)求函數(shù).
BLKPREP_KILL
這個(gè)請(qǐng)求不能完成; 它帶有一個(gè)錯(cuò)誤碼而失敗.
BLKPREP_DEFER
這個(gè)請(qǐng)求這次無(wú)法完成. 它位于隊(duì)列的前面, 但是不能傳遞給請(qǐng)求函數(shù).
準(zhǔn)備函數(shù)被 elv_next_request 在請(qǐng)求返回到你的驅(qū)動(dòng)之前立刻調(diào)用. 如果這個(gè)函數(shù)返回 BLKPREP_DEFER, 從 elv_next_request 返回給你的驅(qū)動(dòng)的返回值是 NULL. 這個(gè)操作描述可能是有用的, 如果, 例如你的設(shè)備已達(dá)到它能夠等候的請(qǐng)求的最大數(shù)目.
為使塊層調(diào)用你的準(zhǔn)備函數(shù), 傳遞它到:
void blk_queue_prep_rq(request_queue_t *queue, prep_rq_fn *func);
缺省地, 請(qǐng)求隊(duì)列沒(méi)有準(zhǔn)備函數(shù).
可同時(shí)有多個(gè)請(qǐng)求被激活的硬件, 常常支持某種被標(biāo)識(shí)的命令排隊(duì)(TCQ). TCQ 簡(jiǎn)單地說(shuō)是關(guān)聯(lián)一個(gè)整數(shù) "tag" 到每個(gè)請(qǐng)求的技術(shù), 注意當(dāng)驅(qū)動(dòng)器完成每個(gè)請(qǐng)求時(shí), 他可告知驅(qū)動(dòng)是哪一個(gè). 在以前的內(nèi)核版本, 實(shí)現(xiàn) TCQ 的塊驅(qū)動(dòng)不得不自己做所有的工作; 在2.6, 一個(gè) TCQ 支持框架已經(jīng)被添加到塊層, 以給所有的驅(qū)動(dòng)來(lái)使用.
如果你的驅(qū)動(dòng)器進(jìn)行標(biāo)記命令排隊(duì), 你應(yīng)當(dāng)在初始化時(shí)通知內(nèi)核這個(gè)事實(shí), 使用:
int blk_queue_init_tags(request_queue_t *queue, int depth, struct blk_queue_tag *tags);
這里, queue 是你的請(qǐng)求隊(duì)列, 而 depth 是你的設(shè)備能夠在任何時(shí)間擁有的等待的標(biāo)記請(qǐng)求的數(shù)目. tags 是一個(gè)可選的指針指向一個(gè) struct blk_queue_tag 結(jié)構(gòu)數(shù)組; 必須有 depth 個(gè). 正常地, tags 可用 NULL, 并且 blk_queue_init_tags 分配這個(gè) 數(shù)組. 如果, 但是, 你需要和多個(gè)設(shè)備分享通用的 tags, 你可傳遞這個(gè)標(biāo)記數(shù)組指針(存儲(chǔ)在 queue_tags 成員)從另一個(gè)請(qǐng)求隊(duì)列. 你應(yīng)當(dāng)從不真正自己分配這個(gè)標(biāo)記數(shù)組; 塊層需要初始化這個(gè)數(shù)組并且不輸出這個(gè)初始化函數(shù)給模塊.
因?yàn)?blk_queue_init_tags 分配內(nèi)存, 它可能失敗. 在那個(gè)情況下它返回一個(gè)負(fù)的錯(cuò)誤碼給調(diào)用者.
如果你的設(shè)備可處理的標(biāo)記的數(shù)目改變了, 你可通知內(nèi)核, 使用:
int blk_queue_resize_tags(request_queue_t *queue, int new_depth);
這個(gè)隊(duì)列鎖必須在這個(gè)調(diào)用期間被持有. 這個(gè)調(diào)用可能失敗, 返回一個(gè)負(fù)錯(cuò)誤碼.
一個(gè)標(biāo)記和一個(gè)請(qǐng)求結(jié)構(gòu)的關(guān)聯(lián)被 blk_queue_start_tag 來(lái)完成, 它必須在成員隊(duì)列鎖被持有時(shí)調(diào)用:
int blk_queue_start_tag(request_queue_t *queue, struct request *req);
如果一個(gè) tag 可用, 這個(gè)函數(shù)分配它給這個(gè)請(qǐng)求, 存儲(chǔ)這個(gè)標(biāo)識(shí)號(hào)在 req->tag, 并且返回 0. 它還從隊(duì)列中解除這個(gè)請(qǐng)求, 并且連接它到它自己的標(biāo)識(shí)跟蹤結(jié)構(gòu), 因此你的驅(qū)動(dòng)應(yīng)當(dāng)小心不從隊(duì)列中解除這個(gè)請(qǐng)求, 如果在使用標(biāo)識(shí). 如果沒(méi)有標(biāo)識(shí)可用, blk_queue_start_tag 將這個(gè)請(qǐng)求留在隊(duì)列并且返回一個(gè)非零值.
當(dāng)一個(gè)給定的請(qǐng)求的所有的傳送都已完成, 你的驅(qū)動(dòng)應(yīng)當(dāng)返回標(biāo)識(shí), 使用:
void blk_queue_end_tag(request_queue_t *queue, struct request *req);
再一次, 你必須持有隊(duì)列鎖, 在調(diào)用這個(gè)函數(shù)之前. 這個(gè)調(diào)用應(yīng)當(dāng)在 end_that_request_first 返回 0 之后進(jìn)行(意味著這個(gè)請(qǐng)求完成), 但要在調(diào)用 end_that_request_last 之前. 記住這個(gè)請(qǐng)求已經(jīng)從隊(duì)列中解除, 因此它對(duì)于你的驅(qū)動(dòng)在此點(diǎn)這樣做可能是一個(gè)錯(cuò)誤.
如果你需要找到關(guān)聯(lián)到一個(gè)給定標(biāo)識(shí)上的請(qǐng)求(當(dāng)驅(qū)動(dòng)器報(bào)告完成, 例如), 使用 blk_queue_find_tag:
struct request *blk_queue_find_tag(request_queue_t *qeue, int tag);
返回值是關(guān)聯(lián)的請(qǐng)求結(jié)構(gòu), 除非有些事情已經(jīng)真的出錯(cuò)了.
如果事情真地出錯(cuò)了, 你的請(qǐng)求可能發(fā)現(xiàn)它自己不得不復(fù)位或者對(duì)其中一個(gè)它的設(shè)備進(jìn)行一些其他的大動(dòng)作. 在這種情況下, 任何等待中的標(biāo)識(shí)命令將不會(huì)完成. 塊層提供一個(gè)函數(shù)可用幫助在這種情況下恢復(fù):
void blk_queue_invalidate_tags(request_queue_t *queue);
這個(gè)函數(shù)返回所有的等待的標(biāo)識(shí)給這個(gè)池, 并且將關(guān)聯(lián)的請(qǐng)求放回請(qǐng)求隊(duì)列. 你調(diào)用這個(gè)函數(shù)時(shí)必須持有隊(duì)列鎖.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: