设备与驱动的匹配

来源:互联网 发布:淘宝里抢的红包怎么用 编辑:程序博客网 时间:2024/05/24 15:37

看了许久,今天终于是了解了驱动及设备的注册及彼此的绑定过程,详细内容请见下文,如有不对地方请指正,多谢了!

一、

先看一下这个

  1. int __init devices_init(void)  
  2. {  
  3.     devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);  
  4.     if (!devices_kset)  
  5.         return -ENOMEM;  
  6.     dev_kobj = kobject_create_and_add("dev", NULL);  
  7.     if (!dev_kobj)  
  8.         goto dev_kobj_err;  
  9.     sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);  
  10.     if (!sysfs_dev_block_kobj)  
  11.         goto block_kobj_err;  
  12.     sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);  
  13.     if (!sysfs_dev_char_kobj)  
  14.         goto char_kobj_err;  
  15.   
  16.     return 0;  
  17.   
  18.  char_kobj_err:  
  19.     kobject_put(sysfs_dev_block_kobj);  
  20.  block_kobj_err:  
  21.     kobject_put(dev_kobj);  
  22.  dev_kobj_err:  
  23.     kset_unregister(devices_kset);  
  24.     return -ENOMEM;  
  25. }
此功能不言而喻

再看

int device_register(struct device *dev)

{

     device_initialize(dev);

     return device_add(dev);

}

  1. void device_initialize(struct device *dev)  
  2. {  
  3.     dev->kobj.kset = devices_kset;  
  4.     kobject_init(&dev->kobj, &device_ktype);  
  5.     INIT_LIST_HEAD(&dev->dma_pools);  
  6.     init_MUTEX(&dev->sem);  
  7.     spin_lock_init(&dev->devres_lock);  
  8.     INIT_LIST_HEAD(&dev->devres_head);  
  9.     device_init_wakeup(dev, 0);  
  10.     device_pm_init(dev);  
  11.     set_dev_node(dev, -1);  
  12. }
  1. int device_add(struct device *dev)  
  2. {  
  3.     struct device *parent = NULL;  
  4.     struct class_interface *class_intf;  
  5.     int error = -EINVAL;  
  6.   
  7.     dev = get_device(dev);  
  8.     if (!dev)  
  9.         goto done;  
  10.   
  11.     if (!dev->p) {  
  12.         error = device_private_init(dev);  
  13.         if (error)  
  14.             goto done;  
  15.     }
  16. /* 
  17.      * for statically allocated devices, which should all be converted 
  18.      * some day, we need to initialize the name. We prevent reading back 
  19.      * the name, and force the use of dev_name() 
  20.      */  
  21.     if (dev->init_name) {  
  22.         dev_set_name(dev, "%s", dev->init_name);  
  23.         dev->init_name = NULL;  
  24.     }  
  25.   
  26.     if (!dev_name(dev))  
  27.         goto name_error;  
  28.   
  29.     pr_debug("device: '%s': %s\n", dev_name(dev), __func__);  
  30.   
  31.     parent = get_device(dev->parent);  
  32.     setup_parent(dev, parent);  
  33.   
  34.     /* use parent numa_node */  
  35.     if (parent)  
  36.         set_dev_node(dev, dev_to_node(parent));  
  37.   
  38.     /* first, register with generic layer. */  
  39.     /* we require the name to be set before, and pass NULL */  
  40.     error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);  
  41.     if (error)  
  42.         goto Error;  
  43.   
  44.     /* notify platform of device entry */  
  45.     if (platform_notify)  
  46.         platform_notify(dev);  
  47.   
  48.     error = device_create_file(dev, &uevent_attr);  
  49.     if (error)  
  50.         goto attrError;  
  51.   
  52.     if (MAJOR(dev->devt)) {  
  53.         error = device_create_file(dev, &devt_attr);  
  54.         if (error)  
  55.             goto ueventattrError;  
  56.   
  57.         error = device_create_sys_dev_entry(dev);  
  58.         if (error)  
  59.             goto devtattrError; 

  60.         devtmpfs_create_node(dev);  
  61.     }  
  62.   
  63.     error = device_add_class_symlinks(dev);  
  64.     if (error)  
  65.         goto SymlinkError;  
  66.     error = device_add_attrs(dev);  
  67.     if (error)  
  68.         goto AttrsError;  
  69.     error = bus_add_device(dev);  
  70.     if (error)  
  71.         goto BusError;  
  72.     error = dpm_sysfs_add(dev);  
  73.     if (error)  
  74.         goto DPMError;  
  75.     device_pm_add(dev);  
  76.   
  77.     /* Notify clients of device addition.  This call must come 
  78.      * after dpm_sysf_add() and before kobject_uevent(). 
  79.      */  
  80.     if (dev->bus)  
  81.         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,  
  82.                          BUS_NOTIFY_ADD_DEVICE, dev);  
  83.   
  84.     kobject_uevent(&dev->kobj, KOBJ_ADD);  
  85.     bus_probe_device(dev);  //设备与驱动的探测绑定再次完成
  86.     if (parent)  
  87.         klist_add_tail(&dev->p->knode_parent,  
  88.                    &parent->p->klist_children);  
  89.   
  90.     if (dev->class) {  
  91.         mutex_lock(&dev->class->p->class_mutex);  
  92.         /* tie the class to the device */  
  93.         klist_add_tail(&dev->knode_class,  
  94.                    &dev->class->p->class_devices);  
  95.   
  96.         /* notify any interfaces that the device is here */  
  97.         list_for_each_entry(class_intf,  
  98.                     &dev->class->p->class_interfaces, node)  
  99.             if (class_intf->add_dev)  
  100.                 class_intf->add_dev(dev, class_intf);  
  101.         mutex_unlock(&dev->class->p->class_mutex);  
  102.     } 
  103. done:  
  104.     put_device(dev);  
  105.     return error;  
  106.  DPMError:  
  107.     bus_remove_device(dev);  
  108.  BusError:  
  109.     device_remove_attrs(dev);  
  110.  AttrsError:  
  111.     device_remove_class_symlinks(dev);  
  112.  SymlinkError:  
  113.     if (MAJOR(dev->devt))  
  114.         device_remove_sys_dev_entry(dev);  
  115.  devtattrError:  
  116.     if (MAJOR(dev->devt))  
  117.         device_remove_file(dev, &devt_attr);  
  118.  ueventattrError:  
  119.     device_remove_file(dev, &uevent_attr);  
  120.  attrError:  
  121.     kobject_uevent(&dev->kobj, KOBJ_REMOVE);  
  122.     kobject_del(&dev->kobj);  
  123.  Error:  
  124.     cleanup_device_parent(dev);  
  125.     if (parent)  
  126.         put_device(parent);  
  127. name_error:  
  128.     kfree(dev->p);  
  129.     dev->p = NULL;  
  130.     goto done;  

  131. 此函数的具体功能就不详细说了,主要看bus_probe_device(dev);
    1. void bus_probe_device(struct device *dev)  
    2. {  
    3.     struct bus_type *bus = dev->bus;  
    4.     int ret;  
    5.   
    6.     if (bus && bus->p->drivers_autoprobe) {  
    7.         ret = device_attach(dev);  
    8.         WARN_ON(ret < 0);  
    9.     }  
    10. }

    这里如果设备的总线存在,且驱动为自动探测的话调用device_attach(dev);

    1. int device_attach(struct device *dev)  
    2. {  
    3.     int ret = 0;  
    4.   
    5.     down(&dev->sem);  
    6.     if (dev->driver) {  //这里如果设备的驱动定义的话,直接绑定设备的驱动节点到驱动的设备链表上,
    7.         ret = device_bind_driver(dev); //此函数源码就不贴了
    8.         if (ret == 0)  
    9.             ret = 1;  
    10.         else {  
    11.             dev->driver = NULL;  
    12.             ret = 0;  
    13.         }  
    14.     } else {  //这里如果设备没有驱动的话,到遍历总线上的驱动,最后调用__device_attach
    15.         pm_runtime_get_noresume(dev);  
    16.         ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); //这里忘了一点,如果此时还总线上还没有驱动的话,就不去变量总线,完成匹配了,带在驱动里完成设备和驱动的匹配工作
    17.         pm_runtime_put_sync(dev);  
    18.     }  
    19.     up(&dev->sem);  
    20.     return ret;  

    __device_attach功能见下分分析

    1. static int __device_attach(struct device_driver *drv, void *data)  
    2. {  
    3.     struct device *dev = data;  
    4.   
    5.     if (!driver_match_device(drv, dev))  //这里首先进行match,这里的match调用的是bus里的match
    6.         return 0;  
    7.   
    8.     return driver_probe_device(drv, dev);  

    接下来再看driver_probe_device(drv, dev);

  1. int driver_probe_device(struct device_driver *drv, struct device *dev)  
  2. {  
  3.     int ret = 0;  
  4.   
  5.     if (!device_is_registered(dev))  
  6.         return -ENODEV;  
  7.   
  8.     pr_debug("bus: '%s': %s: matched device %s with driver %s\n",  
  9.          drv->bus->name, __func__, dev_name(dev), drv->name);  
  10.   
  11.     pm_runtime_get_noresume(dev);  
  12.     pm_runtime_barrier(dev);  
  13.     ret = really_probe(dev, drv);  
  14.     pm_runtime_put_sync(dev);  
  15.   
  16.     return ret;  
  17. }
再看really_probe(dev, drv);
  1. static int really_probe(struct device *dev, struct device_driver *drv)  
  2. {  
  3.     int ret = 0;  
  4.   
  5.     atomic_inc(&probe_count);  
  6.     pr_debug("bus: '%s': %s: probing driver %s with device %s\n",  
  7.          drv->bus->name, __func__, drv->name, dev_name(dev));  
  8.     WARN_ON(!list_empty(&dev->devres_head));  
  9.   
  10.     dev->driver = drv;  
  11.     if (driver_sysfs_add(dev)) {  
  12.         printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",  
  13.             __func__, dev_name(dev));  
  14.         goto probe_failed;  
  15.     }  
  16.   
  17.     if (dev->bus->probe) //此处大家应该很重视吧,总线里的probe一般都为空,所以此处没用到,就此跳过
  18.         ret = dev->bus->probe(dev);  
  19.         if (ret)  
  20.             goto probe_failed;  
  21.     } else if (drv->probe) {  //这里就是你写的驱动里的probe了,在这里才开始执行,呵呵,看到此处有何感慨!
  22.         ret = drv->probe(dev);  
  23.         if (ret)  
  24.             goto probe_failed;  
  25.     }  
  26.   
  27.     driver_bound(dev);  //这里完成设备的驱动节点绑定到驱动的设备链表上,至此完成了设备和驱动的绑定,同时也完成了设备驱动里的东东,注意在加载驱动的时候
  28. bus_add_drver()实现的功能基本和这里的一样,下篇文章将分析
  29.     ret = 1;  
  30.     pr_debug("bus: '%s': %s: bound device %s to driver %s\n",  
  31.          drv->bus->name, __func__, dev_name(dev), drv->name);  
  32.     goto done;  
  33.   
  34. probe_failed:  
  35.     devres_release_all(dev);  
  36.     driver_sysfs_remove(dev);  
  37.     dev->driver = NULL;  
  38.   
  39.     if (ret != -ENODEV && ret != -ENXIO) {  
  40.         /* driver matched but the probe failed */  
  41.         printk(KERN_WARNING  
  42.                "%s: probe of %s failed with error %d\n",  
  43.                drv->name, dev_name(dev), ret);  
  44.     }  
  45.     /* 
  46.      * Ignore errors returned by ->probe so that the next driver can try 
  47.      * its luck. 
  48.      */  
  49.     ret = 0;  
  50. done:  
  51.     atomic_dec(&probe_count);  
  52.     wake_up(&probe_waitqueue);  
  53.     return ret;  

相信大家看到此处,定会万分惊喜终于找的了probe函数在何处执行,也知道了设备如何和驱动配对,绑定的,哦,不对,还没贴出绑定的函数了,如下

  1. static void driver_bound(struct device *dev)  
  2. {  
  3.     if (klist_node_attached(&dev->p->knode_driver)) {  
  4.         printk(KERN_WARNING "%s: device %s already bound\n",  
  5.             __func__, kobject_name(&dev->kobj));  
  6.         return;  
  7.     }  
  8.   
  9.     pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),  
  10.          __func__, dev->driver->name);  
  11.   
  12.     if (dev->bus)  
  13.         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,  
  14.                          BUS_NOTIFY_BOUND_DRIVER, dev);  
  15.   
  16.     klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);  
  17. }
至此我什么也不想说了,下篇文章将讲述驱动配对设备






原创粉丝点击