USB 裝置驅動之裝置接入梳理(一)

2021-10-10 20:12:50 字數 1900 閱讀 4202

主要是註冊hub驅動和建立工作佇列

註冊hub驅動:

if (usb_register(&hub_driver)
這裡引入usb_driver 結構體,先看看hub是如何初始化的

static struct usb_driver hub_driver = ;
建立hub工作佇列

hub_wq = alloc_workqueue("usb_hub_wq", wq_freezable, 0);

if (hub_wq)

return 0;

hub_probe函式:簡單來說如果是支援的hub,則對其進行分配記憶體、初始化和初始化。對於hub_event部分,就一句,但對以後有著深遠的影響,因為這裡是hub接入其他裝置的入口。

init_work(&hub->events, hub_event);
而hub_irq()函式則是決定是否能進入到該入口。且看下面一 一道來

if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)

return 0;

配置整個hub的同時,也在向host註冊一些資訊,比如,發生中斷傳輸就找他——hub_irq()

usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,

hub, endpoint->binterval);

經過以上的註冊、porb、config,hub算是能正常的工作了。如果乙個裝置接入hub,又該如何run起來呢?剛才也說明了irq是入口,看看為啥這麼認為

引數是urb,中斷**的urb?肯定是host過來的,將中斷資訊儲存到urb的buffer中傳遞過來,irq整合資料後喚醒hub workqueue

for (i = 0; i < urb->actual_length; ++i)

bits |= ((unsigned long) ((*hub->buffer)[i]))

<< (i*8);

hub->event_bits[0] = bits;

kick_hub_wq(hub);

kick_hub_wq喚醒hub_event

if (queue_work(hub_wq, &hub->events))

return;

踏平坎坷成大道

鬥罷艱險又出發,又出發!hub_event() 函式,首先是一系列的判斷,作為執行在各大平台的作業系統,必須嚴謹,先判斷是否是自身hub引發的中斷,是不是電壓不穩引起的異常,當然還判斷該hub是否是正常工作的。如果都不是其他因素引起的異常,那就遍歷hub埠,找到發生狀態改變的埠,進行處理。在hub_irq中就將狀態都裝入event_bits中,所以這裡遍歷找到對應的事件。

/* deal with port status changes */

for (i = 1; i <= hdev->maxchild; i++)

}

從這個for迴圈可以得出:

1.event_bits 、change_bits、wakeup_bits中的每乙個bits對應乙個port的狀態,針對這點,hub的spec中有描述

2. hub最多支援8個port

找到有變化的埠後,進行電源設定,然後進入port_event()函式,下一節繼續梳理port_event。

USB 裝置驅動之裝置接入梳理(二)

usb提供了一套自頂向下的識別方法,從hub event出發,檢查是否真的有埠發生了改變,如果坐實是port被觸發了,則進入port event。先去獲取hub的狀態 if hub port status hub,port1,portstatus,portchange 0 return 最終也是呼叫...

USB裝置驅動

1.linux usb架構 usb通訊都是由host端發起的。usb裝置驅動程式分配並初始化乙個urb發給usb core,usb core改一改,發給usb主機控制器驅動,usb主機控制器驅動把它解析成包,在匯流排上進行傳送。usb core是由核心實現的,其實也就是把host control d...

USB裝置驅動

把usb裝置接到pc 右下角彈出 發現android phone 跳出乙個對話方塊,提示你安裝驅動程式 問1.既然還沒有 驅動程式 為何能知道是 android phone 答1.windows裡已經有了usb的匯流排驅動程式,接入usb裝置後,是 匯流排驅動程式 知道你是 android phon...