详解Linux2.6内核中基于platform机制的驱动模型 (经典) (9)

246static int __driver_attach(struct device *dev, void *data)
 247{
 248        struct device_driver *drv = data;
 249
 250        /*
 251         * Lock device and try to bind to it. We drop the error
 252         * here and always return 0, because we need to keep trying
 253         * to bind to devices and some drivers will return an error
 254         * simply if it didn\'t support the device.
 255         *
 256         * driver_probe_device() will spit a warning if there
 257         * is an error.
 258         */
 259
 260        if (dev->parent)        /* Needed for USB */
 261                down(&dev->parent->sem);
 262        down(&dev->sem);


                 //如果该设备尚没有匹配的driver,则尝试匹配。
 263        if (!dev->driver)
 264                driver_probe_device(drv, dev);
 265        up(&dev->sem);
 266        if (dev->parent)
 267                up(&dev->parent->sem);
 268
 269        return 0;
 270}



170/**
 171 * driver_probe_device - attempt to bind device & driver together
 172 * @drv: driver to bind a device to
 173 * @dev: device to try to bind to the driver
 174 *
 175 * First, we call the bus\'s match function, if one present, which should
 176 * compare the device IDs the driver supports with the device IDs of the
 177 * device. Note we don\'t do this ourselves because we don\'t know the
 178 * format of the ID structures, nor what is to be considered a match and
 179 * what is not.
 180 *
 181 * This function returns 1 if a match is found, -ENODEV if the device is
 182 * not registered, and 0 otherwise.
 183 *
 184 * This function must be called with @dev->sem held.  When called for a
 185 * USB interface, @dev->parent->sem must be held as well.
 186 */
 187int driver_probe_device(struct device_driver *drv, struct device *dev)
 188{
 189        int ret = 0;
 190
 191        if (!device_is_registered(dev))
 192                return -ENODEV;
 193        if (drv->bus->match && !drv->bus->match(dev, drv))
 194                goto done;
 195
 196        pr_debug("bus: \'%s\': %s: matched device %s with driver %s/n",
 197                 drv->bus->name, __FUNCTION__, dev->bus_id, drv->name);
 198
 199        ret = really_probe(dev, drv);
 200
 201done:
 202        return ret;
 203}

193,如果该总线上的设备需要进行匹配,则验证是否匹配。对于platform总线,其匹配过程如下:

542/**
 543 * platform_match - bind platform device to platform driver.
 544 * @dev: device.
 545 * @drv: driver.
 546 *
 547 * Platform device IDs are assumed to be encoded like this:
 548 * "<name><instance>", where <name> is a short description of the type of
 549 * device, like "pci" or "floppy", and <instance> is the enumerated
 550 * instance of the device, like \'0\' or \'42\'.  Driver IDs are simply
 551 * "<name>".  So, extract the <name> from the platform_device structure,
 552 * and compare it against the name of the driver. Return whether they match
 553 * or not.
 554 */
 555static int platform_match(struct device *dev, struct device_driver *drv)
 556{
 557        struct platform_device *pdev;
 558
 559        pdev = container_of(dev, struct platform_device, dev);
 560        return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
 561}

560,简单的进行字符串匹配,这也是我们强调platform_device和platform_driver中的name属性需要一致的原因。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjjds.html