国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Linux > 正文

詳解Linux驅(qū)動中,probe函數(shù)何時被調(diào)用

2019-11-02 16:41:09
字體:
供稿:網(wǎng)友

最近看到linux的設(shè)備驅(qū)動模型,關(guān)于Kobject、Kset等還不是很清淅。看到了struct device_driver這個結(jié)構(gòu)時,想到一個問題:它的初始化函數(shù)到底在哪里調(diào)用呢?以前搞PCI驅(qū)動時用pci驅(qū)動注冊函數(shù)就可以調(diào)用它,搞s3c2410驅(qū)動時只要在mach-smdk2410.c中的struct platform_device *smdk2410_devices {}中加入設(shè)備也會調(diào)用。但從來就沒有想過具體的驅(qū)動注冊并調(diào)用probe的過程。

于是打開SourceInsight追蹤了一下:

從driver_register看起:

int driver_register(struct device_driver * drv){    klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);    init_completion(&drv->unloaded);    return bus_add_driver(drv);}

klist_init與init_completion沒去管它,可能是2.6的這個設(shè)備模型要做的一些工作。直覺告訴我要去bus_add_driver。

bus_add_driver中:

都是些Kobject 與 klist 、attr等。還是與設(shè)備模型有關(guān)的。但是其中有一句:

driver_attach(drv);

單聽名字就很像:

void driver_attach(struct device_driver * drv){    bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);}

這個熟悉,遍歷總線上的設(shè)備并設(shè)用__driver_attach。

在__driver_attach中又主要是這樣:

driver_probe_device(drv, dev);

跑到driver_probe_device中去看看:

有一段很重要:

if (drv->bus->match && !drv->bus->match(dev, drv))        goto Done;

明顯,是調(diào)用的驅(qū)動的總線上的match函數(shù)。如果返回1,則可以繼續(xù),否則就Done了。

繼承執(zhí)行的話:

    if (drv->probe) {        ret = drv->probe(dev);        if (ret) {            dev->driver = NULL;            goto ProbeFailed;        }

只要probe存在則調(diào)用之。至此就完成了probe的調(diào)用。

這個過程鏈的關(guān)鍵還是在drv->bus->match ,因為其余的地方出錯的話就是注冊失敗,而只要注冊不失敗且match返回1,那么就鐵定會調(diào)用驅(qū)程的probe了。你可以注冊一個總線類型和總線,并在match中總是返回 1, 會發(fā)現(xiàn),只要struct device_driver中的bus類型正確時,probe函數(shù)總是被調(diào)用.

PCI設(shè)備有自己的總線模型,估計在它的match中就有一個判斷的條件。

static int pci_bus_match(struct device *dev, struct device_driver *drv){    struct pci_dev *pci_dev = to_pci_dev(dev);    struct pci_driver *pci_drv = to_pci_driver(drv);    const struct pci_device_id *found_id;    found_id = pci_match_device(pci_drv, pci_dev);    if (found_id)        return 1;    return 0;}

再往下跟蹤就知道主要是根據(jù)我們熟悉的id_table來的。

-------------------------------另解-----------------------------------------------------------------------------------------------

從driver_register看起,此處我的這里是:

int driver_register(struct device_driver * drv){if ((drv->bus->probe && drv->probe) ||   (drv->bus->remove && drv->remove) ||   (drv->bus->shutdown && drv->shutdown)) {  printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods/n", drv->name);}klist_init(&drv->klist_devices, NULL, NULL);return bus_add_driver(drv);} 
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 嵊泗县| 长葛市| 白水县| 苗栗市| 栾川县| 长寿区| 兴宁市| 张家川| 丘北县| 清远市| 红安县| 威海市| 正镶白旗| 六安市| 平和县| 吕梁市| 湟中县| 当阳市| 凌源市| 拉萨市| 左权县| 泰安市| 龙川县| 贺州市| 克拉玛依市| 北川| 木兰县| 中牟县| 双城市| 富裕县| 日照市| 焉耆| 汶川县| 高碑店市| 红河县| 丹江口市| 无锡市| 越西县| 凤台县| 乳山市| 安仁县|