各種匯流排match匹配函式

2021-06-22 13:18:19 字數 3647 閱讀 1705

當向linux系統匯流排新增裝置或驅動時,總是會呼叫各匯流排對應的match匹配函式來判斷驅動和裝置是否匹配,這些match函式之間都存在一定的差異,本文先對常用的match匹配函式進行講解,以後會陸續新增新的內容。 struct of_device_id

;struct platform_device_id ;

向系統新增平台驅動或新增裝置時會呼叫平台匯流排platform_bus_type中的platform_match函式來匹配平台驅動和平台裝置。

static int platform_match(struct device *dev, struct device_driver *drv)

由platform_match可以看出,驅動和裝置是否匹配可以通過三種方式來進行判斷,首先是通過of_device_id結構:

static inline int of_driver_match_device(struct device *dev, const struct device_driver *drv)

struct of_device_id *of_match_device(const struct of_device_id *matches, const struct device *dev)

const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node)

return null;

}

如果driver中定義了of_device_id,則通過driver中的of_device_id和device中的device_node內容進行匹配判斷,匹配工作由of_match_node來完成,該函式會遍歷of_device_id列表,查詢是否有成員與device_node相匹配,具體由matches的name,type和compatioble來進行對比,如果找到則返回相應的表項,否則返回null.如果沒有定義of_device_id,device_node或不能找到對應的匹配項,則通過第二種方式platform_device_id來進行對比匹配,通過platform_match_id來完成:

static const struct platform_device_id *platform_match_id( const struct platform_device_id *id, struct platform_device *pdev)

id++;

}

return null;

}

platform_match_id函式遍歷platfrom_device_id列表,通過比對平台裝置與id的name來確定是否有匹配項,如果找到匹配的,則返回對應的id項,否則返回null。如果沒有定義platform_device_id或沒有找到匹配項,則通過第三種方式進行匹配,第三種方式通過比對平台裝置和平台驅動的名字,如果相等,則匹配成功,否則失敗。

當向i2c匯流排新增驅動或裝置時會呼叫i2c_device_match來進行匹配判斷,i2c_device_match函式定義如下所示:

static int i2c_device_match(struct device *dev, struct device_driver *drv)

如i2c_device_match所示,i2c通過兩種方式進行匹配裝置和驅動,一種是of_device_id,另一種是i2c_device_id,i2c_device_id資料結構和platform_device_id一樣。i2c裡的兩種匹配方式和之前的platform判斷方式都是一樣,這裡就不展開。

當向usb匯流排上註冊驅動或新增裝置時,就會呼叫usb_match_device進行驅動和裝置配對,函式如下:

static int usb_device_match(struct device *dev, struct device_driver *drv)

else if (is_usb_inte***ce(dev))

return 0;

}從函式可以看出,match分成兩部分,一部分用於匹配usb裝置,另一部分用於匹配usb 介面,對於usb裝置,在初始化時會設定成usb_device_type,而usb介面,則會設成usb_if_device_type。而函式中的is_usb_device和is_usb_inte***ce就是通過這兩個屬性來判別的,如果為判定為裝置,則進入到裝置分支,否則進入到介面分支繼續判斷。

usb裝置驅動通過usb_register_device_driver介面來註冊到系統,而usb介面驅動則通過usb_register來註冊到系統,驅動工程師的工作基本上集中在介面驅動上,所以通常是通過usb_register來註冊usb驅動的。 

不管是裝置驅動usb_device_driver,還是介面驅動usb_driver資料結構中都包含了struct usbdrv_wrap項,其定義如下:

struct usbdrv_wrap

資料結構中的for_devices用來表示該驅動是裝置驅動還是介面驅動,如果為裝置驅動,則在用usb_register_device_driver註冊時,會將該變數for_devices設定成1,而介面驅動則設為0.

usb_device_match中的is_usb_device_driver函式就是通過獲取上而結構中的for_devices來進行判斷是裝置還是介面驅動的,函式定義如下:

static inline int is_usb_device_driver(struct device_driver *drv)

當進入is_usb_device分支後,再通過is_usb_device_driver來判斷是否為裝置驅動,如果是則返回1,表示匹配成功,它接受所有usb裝置。

當進入到介面分支後,也會先用is_usb_device_driver來進行判斷,如果不是裝置驅動則繼續判斷,否則退出;然後再通過usb_match_id函式來判斷裝置和驅動中的usb_device_id是否匹配,usb_match_id定義如下:

const struct usb_device_id *usb_match_id(struct usb_inte***ce *inte***ce,  const struct usb_device_id *id)

return null;

}遍歷介面驅動中的usb_device_id列表項,只要usb_device_id結構中的idvendor,idproduct,deviceclass,binte***ceclass,driver_info項有效就呼叫usb_match_one_id進行判斷,如找到匹配項則函式返回1,否則返回0 。

int usb_match_one_id(struct usb_inte***ce *inte***ce,const struct usb_device_id *id)

usb_match_one_id和函式中的usb_match_device都是圍繞著usb_device_id進行匹配的,該結構定義如下:

struct usb_device_id ;

match_flags用來規定驅動匹配時的具體項,如match_flags包含usb_device_id_match_vendor,則是通過驅動中的usb_device_id和裝置dev中的idvendor來判斷。

各種匯流排match匹配函式

當向linux系統匯流排新增裝置或驅動時,總是會呼叫各匯流排對應的match匹配函式來判斷驅動和裝置是否匹配,這些match函式之間都存在一定的差異,本文先對常用的match匹配函式進行講解,以後會陸續新增新的內容。struct of device id 向系統新增平台驅動或新增裝置時會呼叫平台匯流...

各種匯流排match匹配函式

當向linux系統匯流排新增裝置或驅動 driver register device register 時,總是會呼叫各匯流排對應的match匹配函式來判斷驅動和裝置是否匹配,這些match函式之間都存在一定的差異,本文先對常用的match匹配函式進行講解,以後會陸續新增新的內容。struct of...

match和 in 查詢匹配

首先建立示例資料 all.states as.data.frame state.x77 all.states name rownames state.x77 rownames all.states null 將內建資料集由陣列轉為資料框,然後新增州名為一列,移除行名稱 cold.states all...