when Linux calls PCI driver's probe function? - linux

Before registering a PCI driver, we have to initialize struct pci_driver and pass it to pci_register_driver. One of fields of the structure is a pointer to driver's probe function.
My question is - when the kernel calls driver's probe routine. Is it guaranteed to be right after the call to pci_register_driver or may happen any other time? What is determining this behaviour?
UPDATE
pci_register_driver is a macro expanded into __pci_register_driver, which in turn calls driver_register, and driver_register calls bus_add_driver.
There's a following code in bus_add_driver:
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
driver_attach will call bus_for_each_dev with argument __driver_attach, which will invoke driver_probe_device
And driver_probe_device ultimately calls really_probe:
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
The one thing I'm not sure about, is if the flag drivers_autoprobe gets set for pci_bus.

After the PCI core within your linux kernel has enumerated your device during the link training phase (this occurs by default at boot), it will gather information about the End Point devices connected to it, this includes the Vendor id, and the device id. The PCI core will then iterate through all of the drivers that have been registered to it with the function `pci_register_driver' and see if the driver supports this vendor/device combination.
A driver identifies that it supports that vendor/device combination using the struct pci_device_id id_table field of the pci_driver structure.
A typical implementation would look something like this:
#define VENDOR 0xBEEF // vendor of EP device
#define DEVICE 0x1111 // device id of EP
static struct pci_device_id module_dev_table[] = {
{ PCI_DEVICE(VENDOR, DEVICE)},
{0, },
};
// PCI driver structure used to register this driver with the kernel
static struct pci_driver fpga_driver = {
.id_table = module_dev_table,
.probe = module_probe,
.remove = module_remove,
.suspend = module_suspend,
.resume = module_resume,
};
When the PCI core identifies your driver as a driver that supports a device on the bus, your probe function will then be called.
So to answer your question, NO, your probe function is not guaranteed to be called immediately after you register your driver, and almost certainly will not be. Your probe function will be called immediately after PCI core enumeration/Link training identifies a device which your driver supports.

When kernel detects a PCI device on PCI bus, kernel gets the device name based on the device tree. After this kernel scans through list of registered drivers if any of the drivers handle this device. If yes, then kernel will call probe of that particular driver.

Related

Linux - Is it necessary to register (instantiate) i2c devices before using them?

I'm confused on how userspace programs using Linux's i2c dev interface is able to register (instantiate?) i2c devices.
From my understanding by reading this: https://www.kernel.org/doc/Documentation/i2c/instantiating-devices, it seems we need to either:
Define a i2c_board_info struct with name and address of the i2c
device, do a i2c_register_board_info()
Have a devicetree entry such as this:
i2c1: i2c#400a0000 {
/* ... master properties skipped ... */
clock-frequency = <100000>;
flash#50 {
compatible = "atmel,24c256";
reg = <0x50>;
};
pca9532: gpio#60 {
compatible = "nxp,pca9532";
gpio-controller;
#gpio-cells = <2>;
reg = <0x60>;
};
};
Instantiate devies explicitly by defining a i2c_board_info struct, then call i2c_new_device() in the init of the i2c device driver
But how is this done for user space programs using the i2c-dev interface described here https://www.kernel.org/doc/Documentation/i2c/dev-interface?
I don't have a devicetree entry, and when I grep the code for i2c_board_info, i2c_register_board_info(), or i2c_new_device() I don't find anything. But the code below still works, how?
#include <linux/i2c-dev.h>
void read_from_device(uint8_t *read_data)
{
int result;
file_desc = open("/dev/i2c-2", O_RDWR);
ioctl(file_desc, I2C_SLAVE, device_address);
i2c_smbus_write_byte_data(file_desc, DEVICE_PAGE_ADDRESS, page_number);
result = i2c_smbus_read_byte_data(file_desc, device_register_address);
*read_data = result;
close(file_desc);
}
Does this mean we don't necessarily have to register (instantiate) i2c devices in order to use them? Does that apply to both i2c drivers as well as userspace programs using i2c-dev interface?
The i2c-dev driver binds to the bus (i2c_adapter), not a specific i2c device (i2c_client). So you only need to create the bus device to use i2c-dev and adding devices for the clients isn't necessary. In fact, you'll find i2c-dev will not let you use an I2C address bound to another driver unless you use the I2C_SLAVE_FORCE ioctl.
This is the opposite to the spidev driver, which binds to a specific spi slave device and not the bus as a whole. I2C predates the modern Linux device model and some things are different than is done in other places.
If you want a kernel driver to control the I2C device then there needs to be a device for the driver to bind to. The exception would be so-called "old style" I2C drivers which probe a set of addresses and bind to devices if any are found that appear to be the correct kind.

defining platform devices in - Linux kernel

I am refering following li k to decribe all the drivers used in my embedded Arm linux board as platform devices, need few points to be clarified. Please suggest on these.
http://thomas.enix.org/pub/conf/rmll2010/kernel-architecture-for-drivers.pdf
=============== Defining platform driver ==================
static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
.driver = {
.name = "imx-uart",
.owner = THIS_MODULE,
},
};
================= Defining a platform device ================
static struct platform_device imx_uart1_device = {
.name = "imx-uart",
.id = 0,
.num_resources = ARRAY_SIZE(imx_uart1_resources),
.resource = imx_uart1_resources,
.dev = {
.platform_data = &uart_pdata,
}
};
======== Kernel start up code location - /arch/arm/mach-imx/mx1ads.c ===========
static struct platform_device *devices[] __initdata = {
&cs89x0_device,
&imx_uart1_device,
&imx_uart2_device,
};
static void __init mx1ads_init(void)
{
[...]
platform_add_devices(devices, ARRAY_SIZE(devices));
[...]
}
MACHINE_START(MX1ADS, "Freescale MX1ADS")
[...]
.init_machine = mx1ads_init,
MACHINE_END
===============================
In linux /drivers/ folder if i have 10 folders for 10 different platform drivers. And i want only 6 drivers to be included in kernel source ?
So how will my kernel come to know which driver to include ?
Are platform drivers compiled as modules or statically compiled in the kernel ?
Also what happens when we call platform_add_devices() system call ?
Does all the platform drivers which are included in kernel are loaded into ram before call to platform_add_devices() system call is made ?
At Which path/file in kernel source i can define all platform devices used in my embedded linux system (means where all platform devices used on board are described) ?
Basically platform drivers are registered in the board files (for example /arch/arm/mach-imx/eukrea_mbimx27-baseboard.c). Modern systems use Device Tree approach.
In order to compile a driver it must be first selected (for example via make menuconfig). So if you select 6 drivers, then 6 drivers will be compiled.
platform_add_devices() registers platform drivers (adds them to a list, see drivers/base/platform.c), so that kernel know, which of them to initialize during the boot stage.
Platform drivers are part of the kernel, so they are in RAM as soon as the kernel image itself is loaded.
See this article for more details.
Platform devices (not drivers, like is stated above) are declared in a board file like /arch/arm/mach-*
and made known to the kernel with platform_add_devices().
This board file is statically compiled and linked to the kernel.
platform_add_devices() is not a system call. it is the part of a kernel API platform_device_register() call for registering devices so they can be
later binded with drivers.
Platform drivers are usually statically linked with kernel and when platform_driver_register() is called, kernel tries to bind driver to the device by matching platform_device and platform_driver name property.
If match is made, driver is registered and probe() function of the driver is called.
Obviously devices has to be registered first, before drivers are loaded.
Nowadays device tree files are used instead board files.
Devices from separate device tree blob file are registered by kernel, and matched to driver with compatible string property.
So this property has to be declared within device_driver structure and
device node in device tree file.
Goal is, when you change devices or their properties, you have to recompile just device tree file, and not the kernel itself.

When is the probe method of struct usb_serial_driver called?

Recently I've been reading through Linux usb-serial.c and generic.c, finding that the probe method of struct usb_driver is invoked when usb core detects a new device plugged.
However I couldn't find where the probe method of struct usb_serial_driver is called, seems that this method is used for some tty related setups. Actually, the template driver generic.c didn't implement this probe method.
In usb-serial.c, usb_serial_init() registered:
bus_register(&usb_serial_bus_type)
tty_register_driver(usb_serial_tty_driver)
usb_register(&usb_serial_driver)
usb_serial_generic_register(debug)
usb_serial_generic_register() just set the device's idVendor and idProduct in its generic_device_ids array. and also registered:
usb_serial_register_drivers(&generic_driver, serial_drivers)
it will register generic_driver to the usb_bus_type bus, so device_attach() will found it
you know, usb_serial_register will add driver to the global list:usb_serial_driver_list,
and register the driver to usb-serial bus.
The generic_driver is a middle lay for probe usb-serial drivers. Actually when the hub detected your usb device has been plugged in, then it will call hub_port_connect_change(core/hub.c), it will distribute current to device and enumerate the device. Last, it will get into usb_new_device(udev) and register the device: device_add(&udev->dev), create file node in /sysfs, and probe the corresponding driver. bus_probe_device() -> device_attach , so, the generic_probe will be called here, and then, it will match the device and call usb_serial_probe() -> search_serial_device() -> ... -> type->probe(), it will search the drive on usb_serial_driver_list, then probe the real serial driver.

Linux USB driver probe() problem

I'm currently work on kernel-mode USB driver for Seowon SWU-3220A WiMAX USB modem. It is a complex device (after plugging it appear in system as USB CDROM, and driver needs to switch it to modem mode). My problem is that the probe() function from my driver is never called. I think it because OS uses standard usb mass storage driver instead of my own.
I initialize driver as follow:
#define GDM7213_VENDOR_ID 0x1076
#define GDM7213_PRODUCT_ID 0x7f40
static struct usb_device_id gdm7213_table [] = {
{ USB_DEVICE(GDM7213_VENDOR_ID, GDM7213_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, gdm7213_table);
static struct usb_driver gdm7213_driver = {
.name = "gdm7213",
.probe = gdm7213_probe,
.disconnect = gdm7213_disconnect,
.suspend = gdm7213_suspend,
.resume = gdm7213_resume,
.pre_reset = gdm7213_pre_reset,
.post_reset = gdm7213_post_reset,
.id_table = gdm7213_table,
};
static int gdm7213_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
printk(KERN_INFO "GDM7213 gdm7213_probe()\n");
return 0;
}
static int __init gdm7213_init_module(void)
{
int result;
printk(KERN_INFO "GDM7213 init_module()\n");
result = usb_register(&gdm7213_driver);
if (result)
err("usb_register failed. Error number %d", result);
return result;
}
static void __exit gdm7213_cleanup_module(void)
{
printk(KERN_INFO "GDM7213 cleanup_module()\n");
usb_deregister(&gdm7213_driver);
}
module_init(gdm7213_init_module);
module_exit(gdm7213_cleanup_module);
Can anybody say me where is a bug or suggest any workaround?
If it is the USB mass storage driver stealing it before you get a chance you might want to blacklist the VID/PID for the device with that driver.
Since you mentioned it's a USB WiMAX adapter I'm going to have a wild guess though that it's presenting a USB mass storage device that contains a driver for it on Windows. If that's the case you would be better off working with USB Modeswitch, which already handles this for 3G modems. Typically the devices expect some magic bytes (which often is actually a SCSI eject command) to persuade them to stop being mass storage devices and become the real modem. (That has a different PID normally too).
Even if your device can't be persuaded to show the real device instead of the driver with one of the existing USB Modeswitch rules it would be more appropriate to fix the problem with that than a kernel hack.
Doing it with USB Modeswitch has a number of advantages over what you proposed:
Keeps everything modular:
Your driver only has to care about WiMAX and one VID/PID for the device
The mass storage driver doesn't need to care about crazy devices - it just looks like plugging and unplugging a device. Teaching the mass storage driver about every single one of these sort of devices isn't appropriate, your device doesn't seem to be a special case.
The knowledge about the split personalities of the device is only relevant to USB Modeswitch, which only exists to solve this problem.
It doesn't break the USB mass storage aspects of the device - users might want to view the Windows driver under Linux for some reason, blacklisting this device would make that impossible. This might be important if you end up using some firmware shipped with the Windows driver under Linux too.
It follows the existing setup and keeps your changes local to your module. This might well be important if you want to get your driver in the mainline kernel ever.

What is the sequence followed by the Linux kernel to configure a device?

As I understood after reading the chapter related to The Linux Device Model in the Linux Device Drivers 3rd Edition, when a new device is configured, the kernel (2.6) follows more or less this sequence:
The Device is registered in the driver core (device_register(), what includes device initialization)
A kobject is registered in the device model
It creates an entry in sysfs and provokes a hotplug event
Bus and drivers are checked to see which one matches with the device
Probe
Device is binded to the driver
My main doubt is, in step 1, when is device_register() called and what fields should already be set in the device struct?
Is it called by the bus to which the device is connected? Any example in the code?
Have I misunderstood anything? :)
PCI hotplug code is going to call pci_do_scan_bus() to go through all slots, see if we find a device/bridge and add them to our device tree :
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) {
max = pci_scan_child_bus(bus) //scan bus for all slots and devices in them
pci_bus_add_devices(bus); //add what we find
...
}
The fields in struct device are actually filled up as part of call to pci_scan_child_bus(). Here's the call graph (sort of :)):
pci_scan_child_bus > pci_scan_slot (scan for slots on the bus) > pci_scan_single_device > pci_device_add > device_initialize.
Note that device_initialize() is the first part of device_register(). You will see that the fields of struct device are filled up in pci_device_add after the call to device_initialize(). You can find it under drivers/pci/probe.c in the kernel sources. The struct pci_dev will also be filled up which will later be used by the device specific driver.
The actual addition of the kobject to the device hierarchy happens in pci_bus_add_devices. Here's the call graph :
pci_bus_add_devices > pci_bus_add_device > device_add.
As you can see, this call flow completes the second part of the device_register() function.
So, in short, device_register() consists of : 1. Initialize device and 2. Add device.
pci_device_add does step 1 and pci_bus_add_device does step 2.
Files of interest are : drivers/pci/{pci.c,bus.c,probe.c}
In struct bus type there is pointer to function match, whose job is to match the driver associated with device. So when the device is associated with a bus, then as soon as the device is connected to bus then it is responsiblity of bus to search for the device.
Pls correct me if that is not the case.

Resources