USB裝置 URB請求塊

2021-10-21 04:00:48 字數 3632 閱讀 6450

1.urb 結構體

usb 請求塊(usb request block,urb)是usb 裝置驅動中用來描述與usb 裝置通訊所用的基本載體和核心資料結構,非常類似於網路裝置驅動中的sk_buff 結構體。

structurb ;

2.urb 處理流程

usb 裝置中的每個端點都處理乙個urb 佇列,在佇列被清空之前,乙個urb 的典型生命週期

如下。(1)被乙個usb 裝置驅動建立。

建立urb 結構體的函式為:

struct urb *usb_alloc_urb(int iso_packets, int mem_flags);

iso_packets 是這個urb 應當包含的等時資料報的數目,若為0 表示不建立等時資料報。

mem_flags 引數是分配記憶體的標誌,和kmalloc()函式的分配標誌引數含義相同。如果分配成功,該函式返回乙個urb 結構體指標,否則返回0。

urb 結構體在驅動中不能靜態建立,因為這可能破壞usb 核心給urb 使用的引用計數方法。

usb_alloc_urb()的「反函式」為:

void usb_free_urb(struct urb *urb);

該函式用於釋放由usb_alloc_urb()分配的urb 結構體。

(2)初始化,被安排給乙個特定usb 裝置的特定端點。

對於中斷urb,使用usb_fill_int_urb()函式來初始化urb,如下所示:

void usb_fill_int_urb(struct urb *urb, struct usb_device *dev,unsigned int pipe, void *transfer_buffer,int buffer_length, usb_complete_t complete,void *context, int interval);

urb 引數指向要被初始化的urb 的指標;dev 指向這個urb 要被傳送到的usb 裝置;pipe 是這個urb 要被傳送到的usb 裝置的特定端點;transfer_buffer 是指向傳送資料或接收資料的緩衝區的指標,和urb 一樣,它也不能是靜態緩衝區,必須使用kmalloc()來分配;buffer_length 是transfer_buffer 指標所指向緩衝區的大小;complete 指標指向當這個 urb 完成時被呼叫的完成處理函式;context 是完成處理函式的「上下文」;interval 是這個urb 應當被排程的間隔。

上述函式引數中的pipe 使用usb_sndintpipe()或usb_rcvintpipe()建立。

對於批量urb,使用usb_fill_bulk_urb()函式來初始化urb,如下所示:

void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev,unsigned int pipe, void *transfer_buffer,int buffer_length, usb_complete_t complete,void *context);

除了沒有對應於排程間隔的interval 引數以外,該函式的引數和usb_fill_int_urb()函式的引數含義相同。

上述函式引數中的pipe 使用usb_sndbulkpipe()或者usb_rcvbulkpipe()函式來建立。

對於控制 urb,使用usb_fill_control_urb()函式來初始化urb,如下所示:

void usb_fill_control_urb(struct urb *urb, struct usb_device *dev,unsigned int pipe, unsigned char *setup_packet,void *transfer_buffer, int buffer_length,usb_complete_t complete, void *context);

除了增加了新的setup_packet 引數以外,該函式的引數和usb_fill_bulk_urb()函式的引數含義相同。setup_packet 引數指向即將被傳送到端點的設定資料報。

上述函式引數中的pipe 使用usb_sndctrlpipe()或usb_rcvictrlpipe()函式來建立。

(3)被usb 裝置驅動提交給usb 核心。

在完成第(1)、(2)步的建立和初始化urb 後,urb 便可以提交給usb 核心,通過usb_submit_urb()函式來完成,如下所示:

int usb_submit_urb(struct urb *urb, int mem_flags);

urb 引數是指向urb 的指標,mem_flags 引數與傳遞給kmalloc()函式引數的意義相同,它用於告知usb 核心如何在此時分配記憶體緩衝區。

在提交urb 到usb 核心後,直到完成函式被呼叫之前,不要訪問urb 中的任何成員。

usb_submit_urb()在原子上下文和程序上下文中都可以被呼叫,mem_flags 變數需根據呼叫環

境進行相應的設定,如下所示。

gfp_atomic:在中斷處理函式、底半部、tasklet、定時器處理函式以及urb 完成函式中,在呼叫者持有自旋鎖或者讀寫鎖時以及當驅動將current→state 修改為非 task_running 時,應使用此標誌。

gfp_noio:在儲存裝置的塊i/o 和錯誤處理路徑中,應使用此標誌;

gfp_kernel:如果沒有任何理由使用gfp_atomic 和gfp_noio,就使用gfp_kernel。

如果usb_submit_urb()呼叫成功,即urb 的控制權被移交給usb 核心,該函式返回0;否則,

返回錯誤號。

(4)提交由usb 核心指定的usb 主機控制器驅動。

(5)被usb 主機控制器處理,進行一次到usb 裝置的傳送。

第(4)~(5)步由usb 核心和主機控制器完成,不受usb 裝置驅動的控制。

(6)當urb 完成,usb 主機控制器驅動通知usb 裝置驅動。

在如下3 種情況下,urb 將結束,urb 完成函式將被呼叫。

1、urb 被成功傳送給裝置,並且裝置返回正確的確認。如果urb→status 為0,意味著對於乙個輸出urb,資料被成功傳送;對於乙個輸入urb,請求的資料被成功收到。

2、如果傳送資料到裝置或從裝置接收資料時發生了錯誤,urb→status 將記錄錯誤值。

3、urb 被從usb 核心「去除連線」,這發生在驅動通過usb_unlink_urb()或usb_kill_urb()函式取消urb,或urb 雖已提交,而usb 裝置被拔出的情況下。

當urb 生命結束時(處理完成或被解除鏈結),通過urb 結構體的status 成員可以獲知其原因,

如0 表示傳輸成功,-enoent 表示被usb_kill_urb()殺死,-econnreset 表示被usb_unlink_urb()

殺死,-eproto 表示傳輸中發生了bitstuff 錯誤或者硬體未能及時收到響應資料報,-enodev

表示usb 裝置已被移除,-exdev 表示等時傳輸僅完成了一部分等。

對以上urb 的處理步驟進行乙個總結,圖20.5 給出了乙個urb 的整個處理流程,虛線框的usb_unlink_urb()和usb_kill_urb()並非一定會發生,它只是在urb 正在被usb 核心和主機控制器處理時,被驅動程式取消的情況下才發生。

linux對塊裝置的請求處理

linux對塊裝置請求的處理是一種層次體系結構,可以分為5層 1.vfs 這層對所有檔案系統的一種封裝 這個操作分為2步 a.首先確定包含檔案的檔案系統的block size,然後計算請求的資料報含多少file block。b.呼叫跟檔案系統有關的函式來訪問檔案的inode,確定請求的資料在磁碟上的...

塊裝置請求項佇列及硬碟驅動

1.同乙個程序在寫的過程中就不能發出讀的請求,反之,在讀的過程中也不能發出寫的請求。2.當乙個程序正在對硬碟進行寫或者讀的時候,其他程序就不能發出硬碟操作命令,只能進入睡眠狀態,等待硬碟空閒,而不能做其他事情。所以要解決上面的問題,最好的方法就是定義乙個請求佇列,將程序發出的各種請求放在佇列中,至於...

USB裝置分類

usb裝置分類 usb從裝置的分類可以從usb裝置介面描述符 standard inte ce descriptor 對應的的binte ceclass這乙個byte得到。binte ceclass的典型 為1,2,3,6,7,8,9,10,11,255。分別代表意思為 1 audio 表示乙個音訊...