看完了device看driver,給出device_driver的結構體:
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};
struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};
驅動的注冊:
int driver_register(struct device_driver *drv)
主體部分分為三塊看:
1、other = driver_find(drv->name, drv->bus);
driver_find函數是利用驅動模型的基石kobject和kset結構體的雙向循環連結清單,根據name查找。這裡的kset是bus->p->drivers_kset,也
就是bus上已經挂着的驅動的集合。如果找到了,就有問題了:已經注冊了該驅動,不能再注冊了,kernel會列印error并傳回EBUSY。
如果沒找到,就到了第二步
2、bus_add_driver(drv);
這個過程和bus_add_device比較類似
2.1、建立driver_private和device_driver你中有我 我中有你的親密關系
2.2、priv->kobj.kset = bus->p->drivers_kset; 意味了/bus/xxbus/driver下面就是具體driver的目錄
2.3、
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
調用driver_attach-->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach)
對于bus的klist_devices連結清單上挂着的所有device,都來和我們的driver進行比對,進行比對的函數是__driver_attach
__driver_attach首先調用driver_match_device,也就是總線級别的match函數進行比對
如果沒比對上,就調用driver_probe_device
這裡的函數都是與device中用到的一樣
2.4、klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
将driver加入bus的klist_drivers連結清單中
2.5、driver_create_file(drv, &driver_attr_uevent);
建立uevent屬性檔案
2.6、添加driver指向的bus的驅動屬性檔案bus->drv_attrs
2.7、如果需要的話,添加bind和unbind屬性檔案
2.8、kobject_uevent(&priv->kobj, KOBJ_ADD); 發送uevent
driver的注冊就是這樣了,沒什麼好說的了。。。