usb提供了一套自頂向下的識別方法,從hub_event出發,檢查是否真的有埠發生了改變,如果坐實是port被觸發了,則進入port_event。
先去獲取hub的狀態
最終也是呼叫get_port_stats()函式去獲得想要的狀態,hub也是一類usb裝置,if (hub_port_status(hub, port1, &portstatus, &portchange) < 0)
return;
根據spec對於port狀態的請求static int get_port_status(struct usb_device *hdev, int port1,
void *data, u16 value, u16 length)
return status;
}
狀態字段的定於
驅動也有相同的巨集定義:
/*
* wportchange bit field
* see usb 2.0 spec table 11-22 and usb 2.0 lpm ecn table-4.10
* bits 0 to 5 shown, bits 6 to 15 are reserved
*/#define usb_port_stat_c_connection 0x0001
#define usb_port_stat_c_enable 0x0002
#define usb_port_stat_c_suspend 0x0004
#define usb_port_stat_c_overcurrent 0x0008
#define usb_port_stat_c_reset 0x0010
#define usb_port_stat_c_l1 0x0020
然後引發了一串 if 判斷.../*
122 * wportstatus bit field
123 * see usb 2.0 spec table 11-21
124 */
125 #define usb_port_stat_connection 0x0001
126 #define usb_port_stat_enable 0x0002
127 #define usb_port_stat_suspend 0x0004
128 #define usb_port_stat_overcurrent 0x0008
129 #define usb_port_stat_reset 0x0010
130 #define usb_port_stat_l1 0x0020
131 /* bits 6 to 7 are reserved */
132 #define usb_port_stat_power 0x0100
133 #define usb_port_stat_low_speed 0x0200
134 #define usb_port_stat_high_speed 0x0400
135 #define usb_port_stat_test 0x0800
136 #define usb_port_stat_indicator 0x1000
connect_change 標誌,用來標誌著是不是真的有埠改變了。如果真的改變了,需要處理呼叫hub_port_connect_change()函式。if (portchange & usb_port_stat_c_connection)
if (portchange & usb_port_stat_c_enable)
} if (portchange & usb_port_stat_c_overcurrent)
if (portchange & usb_port_stat_c_reset)
if ((portchange & usb_port_stat_c_bh_reset) //以下是usb3.0相關的狀態
&& hub_is_superspeed(hdev))
if (portchange & usb_port_stat_c_link_state)
if (portchange & usb_port_stat_c_config_error)
總結一下,在那些情況下會使得 connect_change 標誌位 為1?if (connect_change)
hub_port_connect_change(hub, port1, portstatus, portchange);
答:1. 埠對應的hub->change_bits 被置1
2.有裝置接入的時候
3. 遠端喚醒hub埠
port_event() 函式都幹了些啥?
答:判定hub的port發生了什麼(裝置接入、喚醒...),做出相應的響應。
函式原型:
功能:響應物理層或者邏輯層的port改變/* handle physical or logical connection change events.
* this routine is called when:
* a port connection-change occurs;
* a port enable-change occurs (often caused by emi);
* usb_reset_and_verify_device() encounters changed descriptors (as from
* a firmware download)
* caller already locked the hub
*/static void hub_port_connect_change(struct usb_hub *hub, int port1,
u16 portstatus, u16 portchange)
__must_hold(&port_dev->status_lock)
適用於: 埠連線情況發生改變;埠使能情況發生改變等
若hub有指示燈,則開始工作
if (hub->has_indicators)
如支援otg功能,設定標誌位
檢查埠裝置是不是已連線需要被喚醒#ifdef config_usb_otg
/* during hnp, don't repeat the debounce */
if (hub->hdev->bus->is_b_host)
portchange &= ~(usb_port_stat_c_connection |
usb_port_stat_c_enable);
#endif
如果之前沒有不是只需要喚醒,就進入連線處理if ((portstatus & usb_port_stat_connection) && udev &&
udev->state != usb_state_notattached) else if (udev->state == usb_state_suspended &&
udev->persist_enabled) else
} clear_bit(port1, hub->change_bits);
/* successfully revalidated the connection */
if (status == 0)
return;
hub_port_connect 函式接著處理連線相關事務。usb_unlock_port(port_dev);
hub_port_connect(hub, port1, portstatus, portchange);
usb_lock_port(port_dev);
USB 裝置驅動之裝置接入梳理(一)
主要是註冊hub驅動和建立工作佇列 註冊hub驅動 if usb register hub driver 這裡引入usb driver 結構體,先看看hub是如何初始化的 static struct usb driver hub driver 建立hub工作佇列 hub wq alloc workq...
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...