驱动与设备的匹配

至此已不想说多少了,以后路还远着了,现在说多了,以后看来就都变成废话了,所以大家直接看下面代码吧

  1. int driver_register(struct device_driver *drv)  
  2. {  
  3.     int ret;  
  4.     struct device_driver *other;  
  5.   
  6.     BUG_ON(!drv->bus->p);  
  7.   
  8.     if ((drv->bus->probe && drv->probe) ||  
  9.         (drv->bus->remove && drv->remove) ||  
  10.         (drv->bus->shutdown && drv->shutdown))  
  11.         printk(KERN_WARNING "Driver '%s' needs updating - please use "  
  12.             "bus_type methods\n", drv->name);  
  13.   
  14.     other = driver_find(drv->name, drv->bus);  
  15.     if (other) {  
  16.         put_driver(other);  
  17.         printk(KERN_ERR "Error: Driver '%s' is already registered, "  
  18.             "aborting...\n", drv->name);  
  19.         return -EBUSY;  
  20.     }  
  21.   
  22.     ret = bus_add_driver(drv);  //这是重头戏,接下来将剖析他
  23.     if (ret)  
  24.         return ret;  
  25.     ret = driver_add_groups(drv, drv->groups);  
  26.     if (ret)  
  27.         bus_remove_driver(drv);  
  28.     return ret;  
  29. }

请看buss_add_driver(drv);//其实此处和device_add里的bus_probe_device有类似

  1. int bus_add_driver(struct device_driver *drv)  
  2. {  
  3.     struct bus_type *bus;  
  4.     struct driver_private *priv;  
  5.     int error = 0;  
  6.   
  7.     bus = bus_get(drv->bus);  
  8.     if (!bus)  
  9.         return -EINVAL;  
  10.   
  11.     pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);  
  12.   
  13.     priv = kzalloc(sizeof(*priv), GFP_KERNEL);  
  14.     if (!priv) {  
  15.         error = -ENOMEM;  
  16.         goto out_put_bus;  
  17.     }  
  18.     klist_init(&priv->klist_devices, NULL, NULL);  
  19.     priv->driver = drv;  
  20.     drv->p = priv;  
  21.     priv->kobj.kset = bus->p->drivers_kset;  
  22.     error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,  
  23.                      "%s", drv->name);  
  24.     if (error)  
  25.         goto out_unregister;  
  26.   
  27.     if (drv->bus->p->drivers_autoprobe) { //看到此处时候回想起bus_probe_device貌似也有此句呀,好了,继续向下看
  28.         error = driver_attach(drv);  
  29.         if (error)  
  30.             goto out_unregister;  
  31.     }  
  32.     klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); //将此驱动在总线上的节点添加到总线上的驱动链表上
  33.     module_add_driver(drv->owner, drv);  
  34.   
  35.     error = driver_create_file(drv, &driver_attr_uevent);  
  36.     if (error) {  
  37.         printk(KERN_ERR "%s: uevent attr (%s) failed\n",  
  38.             __func__, drv->name);  
  39.     }  
  40.     error = driver_add_attrs(bus, drv);  
  41.     if (error) {  
  42.         /* How the hell do we get out of this pickle? Give up */  
  43.         printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",  
  44.             __func__, drv->name);  
  45.     }  
  46.   
  47.     if (!drv->suppress_bind_attrs) {  
  48.         error = add_bind_files(drv);  
  49.         if (error) {  
  50.             /* Ditto */  
  51.             printk(KERN_ERR "%s: add_bind_files(%s) failed\n",  
  52.                 __func__, drv->name);  
  53.         }  
  54.     }  
  55.   
  56.     kobject_uevent(&priv->kobj, KOBJ_ADD);  
  57.     return 0;  
  58.   
  59. out_unregister:  
  60.     kfree(drv->p);  
  61.     drv->p = NULL;  
  62.     kobject_put(&priv->kobj);  
  63. out_put_bus:  
  64.     bus_put(bus);  
  65.     return error;  
  66. }

接下来看driver_attach(drv);

  1. int driver_attach(struct device_driver *drv)  
  2. {  
  3.     return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//看到此是不是又要感慨一下,
  4. 设备匹配的时候,__device_attach里也有类似的一句bus_for_each_drv(.........,  ....... , .......,  __device_attach),
  5. }
好了,继续看__driver_attach
  1. static int __driver_attach(struct device *dev, void *data)  
  2. {  
  3.     struct device_driver *drv = data;  
  4.   
  5.     /* 
  6.      * Lock device and try to bind to it. We drop the error 
  7.      * here and always return 0, because we need to keep trying 
  8.      * to bind to devices and some drivers will return an error 
  9.      * simply if it didn't support the device. 
  10.      * 
  11.      * driver_probe_device() will spit a warning if there 
  12.      * is an error. 
  13.      */  
  14.   
  15.     if (!driver_match_device(drv, dev))  //看看有没有设备,如没,不匹配
  16.         return 0;  
  17.   
  18.     if (dev->parent) /* Needed for USB */  
  19.         down(&dev->parent->sem);  
  20.     down(&dev->sem);  
  21.     if (!dev->driver)  
  22.         driver_probe_device(drv, dev);  //此处之前是不是已经分析过了呀,呵呵,还想我再贴一下代码吗,好滴,就再贴一下
  23.     up(&dev->sem);  
  24.     if (dev->parent)  
  25.         up(&dev->parent->sem);  
  26.   
  27.     return 0;  

看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

  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) {  
  18.         ret = dev->bus->probe(dev);  
  19.         if (ret)  
  20.             goto probe_failed;  
  21.     } else if (drv->probe) {  
  22.         ret = drv->probe(dev);  
  23.         if (ret)  
  24.             goto probe_failed;  
  25.     }  
  26.   
  27.     driver_bound(dev);  
  28.     ret = 1;  
  29.     pr_debug("bus: '%s': %s: bound device %s to driver %s\n",  
  30.          drv->bus->name, __func__, dev_name(dev), drv->name);  
  31.     goto done;  
  32.   
  33. probe_failed:  
  34.     devres_release_all(dev);  
  35.     driver_sysfs_remove(dev);  
  36.     dev->driver = NULL;  
  37.   
  38.     if (ret != -ENODEV && ret != -ENXIO) {  
  39.         /* driver matched but the probe failed */  
  40.         printk(KERN_WARNING  
  41.                "%s: probe of %s failed with error %d\n",  
  42.                drv->name, dev_name(dev), ret);  
  43.     }  
  44.     /* 
  45.      * Ignore errors returned by ->probe so that the next driver can try 
  46.      * its luck. 
  47.      */  
  48.     ret = 0;  
  49. done:  
  50.     atomic_dec(&probe_count);  
  51.     wake_up(&probe_waitqueue);  
  52.     return ret;  
  53. }
至此,神马都是浮云,你信吗,反正我不信。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值