usb提供了一套自頂向下的識別方法,從hub_event出發,檢查是否真的有埠發生了改變,如果坐實是port被觸發了,則進入port_event。
先去獲取hub的狀態
if (hub_port_status(hub, port1, &portstatus, &portchange) < 0)
return;
最終也是呼叫get_port_stats()函式去獲得想要的狀態,hub也是一類usb裝置,
static int get_port_status(struct usb_device *hdev, int port1,
void *data, u16 value, u16 length)
return status;
}
根據spec對於port狀態的請求
狀態字段的定於
驅動也有相同的巨集定義:
/*
* 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
/*
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
然後引發了一串 if 判斷...
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 標誌,用來標誌著是不是真的有埠改變了。如果真的改變了,需要處理呼叫hub_port_connect_change()函式。
if (connect_change)
hub_port_connect_change(hub, port1, portstatus, portchange);
總結一下,在那些情況下會使得 connect_change 標誌位 為1?
答:1. 埠對應的hub->change_bits 被置1
2.有裝置接入的時候
3. 遠端喚醒hub埠
port_event() 函式都幹了些啥?
答:判定hub的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)
功能:響應物理層或者邏輯層的port改變
適用於: 埠連線情況發生改變;埠使能情況發生改變等
若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;
如果之前沒有不是只需要喚醒,就進入連線處理
usb_unlock_port(port_dev);
hub_port_connect(hub, port1, portstatus, portchange);
usb_lock_port(port_dev);
hub_port_connect 函式接著處理連線相關事務。 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...