On Sat, Jan 30, 2016 at 2:41 PM, Bjørn Mork <[email protected]> wrote: > Henrique Montenegro <[email protected]> writes: > > > Hello list, > > > > I am reading through the e1000 driver and trying to figure out how the > > probe function on it gets called. > > > > The driver initialization function calls pci_register_driver: > > > > > ----------------------------------------------------------------------------->8 > > static struct pci_driver e1000_driver = { > > .name = e1000_driver_name, > > .id_table = e1000_pci_tbl, > > .probe = e1000_probe, > > .remove = e1000_remove, > > // ... > > }; > > > > static int __init e1000_init_module(void) > > { > > // ... > > ret = pci_register_driver(&e1000_driver); > > // ... > > } > > > ----------------------------------------------------------------------------->8 > > > > And pci_register_driver is defined as (on linux/pci.h): > > > > > ----------------------------------------------------------------------------->8 > > #define pci_register_driver(driver) \ > > __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME) > > > ----------------------------------------------------------------------------->8 > > > > Function __pci_register_driver is defined as (drivers/pci/pci-driver.c): > > > > > ----------------------------------------------------------------------------->8 > > int __pci_register_driver(struct pci_driver *drv, struct module *owner, > > const char *mod_name) > > { > > /* initialize common driver fields */ > > drv->driver.name = drv->name; > > drv->driver.bus = &pci_bus_type; > > drv->driver.owner = owner; > > drv->driver.mod_name = mod_name; > > > > spin_lock_init(&drv->dynids.lock); > > INIT_LIST_HEAD(&drv->dynids.list); > > > > /* register with core */ > > return driver_register(&drv->driver); > > } > > EXPORT_SYMBOL(__pci_register_driver); > > > ----------------------------------------------------------------------------->8 > > > > This is the point where I am getting lost. I can't figure out how the > Kernel > > will know about the functions defined in the e1000_driver struct > mentioned > > before, since it does not seem to pass a reference to it anywhere. > > > > How does the kernel know where the probe function for this module is in > this > > case? To be honest, for any driver that calls pci_register_driver, how > will > > the > > kernel know where the probe function is since it does not seem like it is > > being passed to driver_register? > > The magic is in the 'drv->driver.bus = &pci_bus_type;' assigment. This > is where the driver core will look for functions knowing how to handle > this specific driver. See Documentation/driver-model/bus.txt etc > > Look at the defintion of pci_bus_type in drivers/pci/pci-driver.c : > > struct bus_type pci_bus_type = { > .name = "pci", > .match = pci_bus_match, > .uevent = pci_uevent, > .probe = pci_device_probe, > .remove = pci_device_remove, > .shutdown = pci_device_shutdown, > .dev_groups = pci_dev_groups, > .bus_groups = pci_bus_groups, > .drv_groups = pci_drv_groups, > .pm = PCI_PM_OPS_PTR, > }; > EXPORT_SYMBOL(pci_bus_type); > > And then look at the different callbacks. These explain how the generic > &drv->driver above is turned back into a pci_driver on probing: > > static int pci_device_probe(struct device *dev) > { > int error; > struct pci_dev *pci_dev = to_pci_dev(dev); > struct pci_driver *drv = to_pci_driver(dev->driver); > > > to_pci_dev() and to_pci_driver() are just macros simplifying the usual > container_of trick. From include/linux/pci.h : > > #define to_pci_dev(n) container_of(n, struct pci_dev, dev) > .. > #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) > > > > Hope this helps. > > > Bjørn > > _______________________________________________ > Kernelnewbies mailing list > [email protected] > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
FWIW, when unsure as to how driver functions such as probe() are called, I've often found dump_stack() [1][2][3] to be extremely helpful. (Of course, this assumes you're able to execute the driver...) [1] http://kernelnewbies.org/KernelHacking-HOWTO/Debugging_Kernel [2] http://www.stlinux.com/devel/debug/backtrace [3] http://processors.wiki.ti.com/index.php/Enabling_Stack_Dumping_in_Linux_Kernel
_______________________________________________ Kernelnewbies mailing list [email protected] http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
