Why is the probe method needed in Linux device drivers in addition to init?

LinuxOperating SystemLinux Kernel

Linux Problem Overview


In the linux kernel, what does the probe() method, that the driver provides, do? How different is it from the driver's init function, i.e. why can't the probe() functions actions be performed in the driver's init function ?

Linux Solutions


Solution 1 - Linux

Different device types can have probe() functions. For example, PCI and USB devices both have probe() functions.

If you're talking about PCI devices, I would recommend you read chapter 12 of http://lwn.net/Kernel/LDD3/">Linux Device Drivers, which covers this part of driver initialization. USB is covered in chapter 13.

Shorter answer, assuming PCI: The driver's init function calls pci_register_driver() which gives the kernel a list of devices it is able to service, along with a pointer to the probe() function. The kernel then calls the driver's probe() function once for each device.

This probe function starts the per-device initialization: initializing hardware, allocating resources, and registering the device with the kernel as a block or network device or whatever it is.

That makes it easier for device drivers, because they never need to search for devices or worry about finding a device that was hot-plugged. The kernel handles that part and notifies the right driver when it has a device for you to handle.

Solution 2 - Linux

@Bandicoot : probe() will be called to make sure that the device exist and the functionality is fine.If device is not hot-pluggable, functionality of probe() can be put inside init() method.This will reduce driver's run time memory footprint. P.S link

Probe() happens at the time of device boot or when device is connected.For a "platform" device the probe function is invoked when a platform device is registered and it's device name matches the name specified on the device driver. P.S link

The i2c_detect function probes the I2C adapter, looking for the different addresses specified in the addr_data structure. If a device is found, the chip_detect function then is called. P.S link.

One link that will surely clear your doubt. P.S link

In kernel 2.4.29, i can show you that how does probe happen ? Please see below (File name: drivers/acorn/char/pcf8583.c)

static struct i2c_driver pcf8583_driver = {
name:       "PCF8583",
id:     I2C_DRIVERID_PCF8583,
flags:      I2C_DF_NOTIFY,
attach_adapter: pcf8583_probe, /* This will be called from i2c-core.c P.S see below function i2c_add_driver()*/
detach_client:  pcf8583_detach,
command:    pcf8583_command

};

File Name: drivers/i2c/i2c-core.c

int i2c_add_driver(struct i2c_driver *driver)
{
    ........................
    ........................

    /* now look for instances of driver on our adapters
     */
    if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
        for (i=0;i<I2C_ADAP_MAX;i++)
            if (adapters[i]!=NULL)
                /* Ignore errors */
                driver->attach_adapter(adapters[i]); /*This is a location from where probe is called. Pointer **driver** is of type **pcf8583_driver** which you have passed into this function*/
    }
    ADAP_UNLOCK();
    return 0;
}

Few important links:

  1. http://www.slideshare.net/varunmahajan06/i2c-subsystem-in-linux2624

  2. http://www.programering.com/a/MjNwcTMwATM.html

  3. http://www.linuxjournal.com/article/6717

  4. http://www.developermemo.com/2943157/

  5. http://free-electrons.com/doc/kernel-architecture.pdf

  6. http://www.techques.com/question/1-3014627/Probe-problem-when-writing-a-I2C-device-driver

In PCI for kernel-2.4.29, it gets called when vendor and device id are identified. PCI bus driver do this for you. Please see below code:

File Name: drivers/pci/pci.c

static int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
{
   const struct pci_device_id *id;
   int ret = 0;
   if (drv->id_table) {
    id = pci_match_device(drv->id_table, dev); /* check for device presence*/
    if (!id) {
     ret = 0;
     goto out;
    }
   } else
  id = NULL;
  dev_probe_lock();
  if (drv->probe(dev, id) >= 0) { /* This is a location from where probe is called*/
   dev->driver = drv;
   ret = 1;
   }
   dev_probe_unlock();
  out:
  return ret;
}

Solution 3 - Linux

Init(void) // runs once when the driver/module is invoked and sets things up for the kernel driver machine.

Probe(*pdev) // is used by the kernel driver machine as needed to detect and install actual devices

Solution 4 - Linux

The drivers xxx_init_module() function calls pci_register_driver(struct pci_driver *drv) by passing reference to structure of type pci_driver. struct pci_driver is an important structure all PCI drivers should have, which gets initialized with variables like drivers name, table list of PCI devices the driver can support, callback routines for the PCI core subsystem.

The drivers pci_driver structure has important member fields listed below:

  1. name – Name to the driver which is unique among all PCI drivers in the kernel. It will appear under /sys/bus/pci/drivers.

  2. pci_device_id – A table of device identification data consists type of chips this driver supports.

  3. probe – The address of xxx_probe() function.

  4. remove/suspend/resume/shutdown – address to the function that the PCI core system calls when PCI device is removed/suspended/resumed/shutdown respectively. Generally used by upper layers for power management.

For more information on how the probing of driver executed from PCI core refer Linux Device Driver Init.

Solution 5 - Linux

Multiple devices and hotplug

  1. You are running a large server with many PICe connected GPUs accelerators. At some point you decide to buy more GPUs for the free slots.

    If we used init, then we'd have to rmmod and insmod the module. But that would require stopping all connected GPUs, which causes downtime.

    With probe, we just plug in the new GPUs do a rescan.

  2. PCIe hotplug wouldn't be possible otherwise: https://electronics.stackexchange.com/questions/208767/does-pcie-hotplug-actually-work-in-practice

QEMU edu PCI device example

QEMU has an educational PCI device called edu, which allows us to easily test when probe is called.

First, we need a minimal Linux kernel PCI driver for it, which I've written here.

We can start with the device attached with:

-device edu

but even more interestingly, we can attach and remove the device from the QEMU monitor as well, Ctrl + Alt + 2 on SDL GUI or -monitor telnet::45454,server,nowait on CLI, with the commands:

device_add edu
device_del edu

If the device is attached at boot:

  • probe is called as soon as we insmod the module

  • dmesg contains a line of type: pci 0000:00:04: [1234:11e8] ... that shows that our device was probed to BDF 0000:00:04.

    We know that this is our device, because the vendor is 0x1234 and device id 11e8 in the QEMU source.

    So we conclude that PCI devices are probed at boot, and stored in a list somewhere.

If we attach the device after boot from the monitor:

Solution 6 - Linux

Linux kernel uses a hardware device matching a software device driver process. init is called very early, and registers probe function and a hardware device name like "taiko_sound_card", to the kernel. This is to tell kernel that "I am sw driver for this device of this name". When the kernel goes through hw devices (device tree or bus enum), and finds a match, it will call your registered probe function. Now your sw device driver owns the hw device.

If no matching device is found, your probe may never get called. This is why typically init is tiny and probe does all the init work.

Solution 7 - Linux

Probing is done when the probe() method is called by function pointer inside a structure which is used to device binding with default or custom platform data regarding to device. drivers uses lots of information about device so that the probing provides such information to drivers when an entry in the id_table name field matches device name will be probe.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBandicootView Question on Stackoverflow
Solution 1 - LinuxEric SeppanenView Answer on Stackoverflow
Solution 2 - LinuxManishView Answer on Stackoverflow
Solution 3 - LinuxfbpView Answer on Stackoverflow
Solution 4 - LinuxSunil BojanapallyView Answer on Stackoverflow
Solution 5 - LinuxCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 6 - LinuxLiyong ZhouView Answer on Stackoverflow
Solution 7 - LinuxYûvʀʌj SɩŋʛʜView Answer on Stackoverflow