各種匯流排match匹配函式

2021-07-02 14:00:52 字數 3952 閱讀 4817

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

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

static intplatform_match(struct device *dev, struct device_driver *drv)

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

1. driver->of_match_table與device->of_node匹配。具體分為name、type或compatible其中乙個字段進行匹配。

2.如果存在driver->id_table,就匹配id_talbe與pdev的name欄位是否匹配。(常用於一驅動對應多裝置的情況)

3.直接匹配driver與pdev的name欄位。

首先是通過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)

if (is_usb_device(dev)) 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

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 {

/* which fields to match against? */

__u16 match_flags;

/* used for product specific matches; range is inclusive */

__u16 idvendor;

__u16 idproduct;

__u16 bcddevice_lo;

__u16 bcddevice_hi;

/* used for device class matches */

__u8 bdeviceclass;

__u8 bdevicesubclass;

__u8 bdeviceprotocol;

/* used for inte***ce class matches */

__u8 binte***ceclass;

__u8 binte***cesubclass;

__u8 binte***ceprotocol;

/* not matched against */

kernel_ulong_tdriver_info;

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

match和 in 查詢匹配

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