Specify when the probe function is called in the Linux driver

  • 2020-05-14 05:51:42
  • OfStack

Recently I saw the device driver model of linux, but it is not clear about Kobject, Kset, etc. When I saw the structure struct device_driver, I thought of a question: where exactly is the initialization function called? In the past, the PCI driver could be called by using the pci driver registration function, while the s3c2410 driver could be called by adding the struct platform_device *smdk2410_devices {} to the mach-smdk2410.c struct platform_device *smdk2410_devices {}. But never thought about the specific driver registration and call probe procedure.

So I opened SourceInsight and tracked 1:

From driver_register:


int driver_register(struct device_driver * drv)
{
    klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);
    init_completion(&drv->unloaded);
    return bus_add_driver(drv);
}

klist_init and init_completion don't care about it, maybe it is the work of the device model of 2.6. My gut tells me to go to bus_add_driver.

bus_add_driver:

Kobject, klist, attr, etc. Again, it has to do with the device model. But there is one sentence:

driver_attach(drv);

The name sounds like:


void driver_attach(struct device_driver * drv)
{
    bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

This familiar, traverse the device on the bus and use s 58en_attach.

This is mainly the case with s 63en_attach:

driver_probe_device(drv, dev);

Go to driver_probe_device and see:

There is one important paragraph:


if (drv->bus->match && !drv->bus->match(dev, drv))
        goto Done;

Obviously, the match function is called on the driver's bus. If it returns 1, it can continue, otherwise it's Done.

Words of inheritance and execution:


    if (drv->probe) {
        ret = drv->probe(dev);
        if (ret) {
            dev->driver = NULL;
            goto ProbeFailed;
        }

Call probe as long as it exists. This completes the call to probe.

The key to this process chain is drv- > bus- > match, because the rest of it is a registration failure, and as long as the registration does not fail and match returns 1, then the probe of the drive will definitely be called. You can register a bus type and bus and always return 1 in match. You will find that the probe function is always called as long as the bus type in struct device_driver is correct.

The PCI device has its own bus model, and it is estimated that there is one judgment condition in its match.


static int pci_bus_match(struct device *dev, struct device_driver *drv)
{
    struct pci_dev *pci_dev = to_pci_dev(dev);
    struct pci_driver *pci_drv = to_pci_driver(drv);
    const struct pci_device_id *found_id;

    found_id = pci_match_device(pci_drv, pci_dev);
    if (found_id)
        return 1;

    return 0;
}

The next trace is based on the familiar id_table.

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - another solution -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -

From driver_register, here is my here:


int driver_register(struct device_driver * drv)
{
if ((drv->bus->probe && drv->probe) ||
   (drv->bus->remove && drv->remove) ||
   (drv->bus->shutdown && drv->shutdown)) {
  printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
}
klist_init(&drv->klist_devices, NULL, NULL);
return bus_add_driver(drv);
} 

klist_init is irrelevant, don't worry about it. For details, go to bus_add_driver:


int bus_add_driver(struct device_driver *drv)
{
//1. First, kobject_set_name(&drv->kobj, "%s", drv->name);
//2. again kobject_register(&drv->kobj)
//3. Then it calls: driver_attach(drv)
}

int driver_attach(struct device_driver * drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

S s s 137en_attach that are actually working:


static int __driver_attach(struct device * dev, void * data)
{
...
if (!dev->driver)
  driver_probe_device(drv, dev);
...
}

int driver_probe_device(struct device_driver * drv, struct device * dev)
{
...
//1. First the judgment bus Whether or not match : 
if (drv->bus->match && !drv->bus->match(dev, drv))
  goto done;
//2. Concrete implementation probe : 
ret = really_probe(dev, drv);
...
}

really_probe is the function we're looking for:


static int really_probe(struct device *dev, struct device_driver *drv)
{
...
//1. First, the driver of the call belongs to the bus probe Function: 
if (dev->bus->probe) {
  ret = dev->bus->probe(dev);
  if (ret)
  goto probe_failed;

} else if (drv->probe) {
//2. Call in your driver probe Function: 
  ret = drv->probe(dev);
  if (ret)
  goto probe_failed;
}
...

}

Among them, the drv - > probe(dev) is the actual probe function that calls your driver's implementation.

The probe function is called in response to the question in the title of this article.


Related articles: