/** * device_bind_driver - bind a driver to one device. * @dev: device. * * Allow manual attachment of a driver to a device. * Caller must have already set @dev->driver. * * Note that this does not modify the bus reference count * nor take the bus's rwsem. Please verify those are accounted * for before calling this. (It is ok to call with no other effort * from a driver's probe() method.) * * This function must be called with the device lock held. */ int device_bind_driver(struct device *dev) { int ret; ret = driver_sysfs_add(dev); if (!ret) driver_bound(dev); return ret; }
/* 将设备和驱动绑定 */ int device_bind_driver(struct device *dev) { int ret; ret = driver_sysfs_add(dev); /* 该函数用来在sysfs文件系统中建立绑定的设备与驱动程序直接的链接符号文件 */ if (!ret) driver_bound(dev); return ret; }
static int really_probe(struct device *dev, struct device_driver *drv) { int ret = 0; atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", drv->bus->name, __func__, drv->name, dev_name(dev)); WARN_ON(!list_empty(&dev->devres_head)); dev->driver = drv; if (driver_sysfs_add(dev)) { printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); goto probe_failed; } if (dev->bus->probe) { ret = dev->bus->probe(dev); pr_debug("dev->bus->probe: '%s': %s(line:%d): probing driver %s \n",//add by hui drv->bus->name, __func__,__LINE__, drv->name); if (ret) goto probe_failed; } else if (drv->probe) { ret = drv->probe(dev); pr_debug("drv->probe: '%s': %s(line:%d): probing driver %s \n",//add by hui drv->bus->name, __func__,__LINE__, drv->name); if (ret) goto probe_failed; } driver_bound(dev); ret = 1; pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); goto done; probe_failed: devres_release_all(dev); driver_sysfs_remove(dev); dev->driver = NULL; if (ret != -ENODEV && ret != -ENXIO) { /* driver matched but the probe failed */ printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev_name(dev), ret); } /* * Ignore errors returned by ->probe so that the next driver can try * its luck. */ ret = 0; done: atomic_dec(&probe_count); wake_up(&probe_waitqueue); return ret; }
/* 该函数用于真正的探测实际的设备 */ static int really_probe(struct device *dev, struct device_driver *drv) { int ret = 0; atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", drv->bus->name, __func__, drv->name, dev_name(dev)); WARN_ON(!list_empty(&dev->devres_head)); dev->driver = drv; /* 将当前驱动程序对象drv赋值给dev->driver*/ if (driver_sysfs_add(dev)) { printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); goto probe_failed; } if (dev->bus->probe) { /* 如果定义了探测设备的方法dev->bus->probe,则调用该方法来探测设备 */ ret = dev->bus->probe(dev); /* 用来探测当前的设备是否适合当前的驱动 */ if (ret) goto probe_failed; } else if (drv->probe) { /* 否则如果定义了 探测设备的方法drv->probe(),则调用该方法来探测设备*/ ret = drv->probe(dev); /* 用来探测当前的设备是否适合当前的驱动以及当前设备是否处于工作状态等 */ if (ret) goto probe_failed; } driver_bound(dev); /* 如果探测成功则最后调用该函数来将驱动程序的一些数据信息加入到dev对象中 */ ret = 1; pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); goto done; probe_failed: devres_release_all(dev); driver_sysfs_remove(dev); dev->driver = NULL; if (ret != -ENODEV && ret != -ENXIO) { /* driver matched but the probe failed */ printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev_name(dev), ret); } /* * Ignore errors returned by ->probe so that the next driver can try * its luck. */ ret = 0; done: atomic_dec(&probe_count); wake_up(&probe_waitqueue); return ret; }
static int really_probe(struct device *dev, struct device_driver *drv) { int ret = 0; atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", drv->bus->name, __func__, drv->name, dev_name(dev)); WARN_ON(!list_empty(&dev->devres_head)); dev->driver = drv; if (driver_sysfs_add(dev)) { printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); goto probe_failed; } if (dev->bus->probe) { ret = dev->bus->probe(dev); if (ret) goto probe_failed; } else if (drv->probe) { ret = drv->probe(dev); if (ret) goto probe_failed; } driver_bound(dev); ret = 1; pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); goto done; probe_failed: devres_release_all(dev); driver_sysfs_remove(dev); dev->driver = NULL; if (ret != -ENODEV && ret != -ENXIO) { /* driver matched but the probe failed */ printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev_name(dev), ret); } #ifdef CONFIG_MACH_LGE_MMC_REFRESH //FW KIMBYUNGCHUL 20110516 [START] if (ret == 0xbcbc) { /* driver matched but the probe failed */ printk(KERN_WARNING "[microSD]%s: probe of %s failed with error %d\n", drv->name, dev_name(dev), ret); }else ret = 0; #else /* * Ignore errors returned by ->probe so that the next driver can try * its luck. */ ret = 0; #endif //FW KIMBYUNGCHUL 20110516 [END] done: atomic_dec(&probe_count); wake_up(&probe_waitqueue); return ret; }