linux设备驱动模型

Bus对应ksetdriverdevice对应kobject

Bus结构体包含2klist,分别是driverdevice的链表,driverdevice中对应包含klist_node来插入链表

Driver结构体中包含1klist,是device的链表,device中对应再包含一个klist_node来插入链表

 

 

/**

 * bus_add_driver - Add a driver to the bus.

 * @drv: driver.

 */

int bus_add_driver(struct device_driver *drv)

{

         struct bus_type *bus;

         struct driver_private *priv; /* 作为device_driver一部分,包含kobject结构体 */

         int error = 0;

 

         bus = bus_get(drv->bus); /* 增加计数 */

         if (!bus)

                   return -EINVAL;

 

         pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);

    /* 分配空间,下文初始化,管理driver的设备驱动模型 */

         priv = kzalloc(sizeof(*priv), GFP_KERNEL);

         if (!priv) {

                   error = -ENOMEM;

                   goto out_put_bus;

         }

    /*初始化klist成员,driver有一个klist结构,作为驱动管理的设备链表 */

         klist_init(&priv->klist_devices, NULL, NULL);

         priv->driver = drv;

         drv->p = priv;

   /* driverkobjetkset成员指向bus的成员,表示driver属于bus */

         priv->kobj.kset = bus->p->drivers_kset;

   /* 初始化driverkobject,并且将它插到buskset中,同时在sysfs中在bus的目录下创建子目录。*/

         error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,

                                          "%s", drv->name);

         if (error)

                   goto out_unregister;

    /* driver插入busklist链表 */

         klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);

   /* 如果bus支持driver的自动搜索设备,则driver进入bus的设备链表,寻找匹配设备并调用probe函数初始化设备 */

         if (drv->bus->p->drivers_autoprobe) {

                   error = driver_attach(drv);

                   if (error)

                            goto out_unregister;

         }

    /* /sys/module/目录下显示driver */

         module_add_driver(drv->owner, drv);

 

    // /sys/bus/driver/目录下创建uevent file

         error = driver_create_file(drv, &driver_attr_uevent);

         if (error) {

                   printk(KERN_ERR "%s: uevent attr (%s) failed\n",

                            __func__, drv->name);

         }

    /*/sys/bus/driver/目录下创建各种属性文件 */

         error = driver_add_attrs(bus, drv);

         if (error) {

                   /* How the hell do we get out of this pickle? Give up */

                   printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",

                            __func__, drv->name);

         }

 

         if (!drv->suppress_bind_attrs) {

                   error = add_bind_files(drv);

                   if (error) {

                            /* Ditto */

                            printk(KERN_ERR "%s: add_bind_files(%s) failed\n",

                                     __func__, drv->name);

                   }

         }

 

         return 0;

 

out_unregister:

         kobject_put(&priv->kobj);

         kfree(drv->p);

         drv->p = NULL;

out_put_bus:

         bus_put(bus);

         return error;

}

 

每个kobject必须有一个release方法,kobject嵌入的对象会一直存在,直到该方法被调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值