关于Probe分析

原创文章,转载请注明出处.转载自: Li Haifeng's Blog
本文链接地址: 关于Probe分析

从probe函数说起

每一个driver module,只要是挂载在platform bus这根虚拟总线上的,无一例外都需要自己实现一个probe函数。这个probe函数将会做真正的驱动加载操作。以pxa688的uart驱动为例:

drivers/tty/serial/pxa.c:
840 static struct platform_driver serial_pxa_driver = {
841         .probe          = serial_pxa_probe,
842         .remove         = serial_pxa_remove,
843
844         .driver         = {
845                 .name   = “pxa2xx-uart”,
846                 .owner  = THIS_MODULE,
847 #ifdef CONFIG_PM
848                 .pm     = &serial_pxa_pm_ops,
849 #endif
850         },
851 };
840~851定义了一个platform类型总线上驱动 serial_pxa_driver.其内部的成员变量中probe和remove以及driver成员都需要自己实现。其中,probe是用于驱动被加载的时候用;remove用于驱动被卸载的时候(如果驱动是built-in进kernel的,在runtime时,是没有模块这个概念的。所以,卸载仅仅是对于编译为module的ko模块–因为它才有可能被rmmod ^-^);.driver.name是用于驱动匹配设备的,这个成员不能少,并且和设备的name要一模一样(在驱动去寻找它的归属设备时,就是用这种简单的方式);.driver.owner这个成员在所有的模块中都是一成不变的THIS_MODULE,这个THIS_MODULE是非常“有故事”的:如果built-in进kernel,那么它为NULL;如果是一个模块,那么是一个struct module的指针值。这个指针值是在模块被modprobe或者insmod的时候由kernel生成一个struct module对象,并由sys_init_module函数返回;847~849是用于电源管理的。
重点和难点都集中在probe函数,上述的其余几个成员都非常简单。下面来看一下pxa688的uart probe函数具体长啥样,做啥工作的:
765 static int serial_pxa_probe(struct platform_device *dev)
766 {
767         struct uart_pxa_port *sport;
768         struct resource *mmres, *irqres;
769         int ret;
770
771         mmres = platform_get_resource(dev, IORESOURCE_MEM, 0);
772         irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0);
773         if (!mmres || !irqres)
774                 return -ENODEV;
775
776         sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL);
777         if (!sport)
778                 return -ENOMEM;
779         
780         sport->clk = clk_get(&dev->dev, NULL);
781         if (IS_ERR(sport->clk)) {
782                 ret = PTR_ERR(sport->clk);
783                 goto err_free;
784         }
785
786         sport->port.type = PORT_PXA;
787         sport->port.iotype = UPIO_MEM;
788         sport->port.mapbase = mmres->start;
789         sport->port.irq = irqres->start;
790         sport->port.fifosize = 64;
791         sport->port.ops = &serial_pxa_pops;
792         sport->port.line = dev->id;
793         sport->port.dev = &dev->dev;
794         sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
795         sport->port.uartclk = clk_get_rate(sport->clk);
796
797         switch (dev->id) {
798         case 0: sport->name = “FFUART”; break;
799         case 1: sport->name = “BTUART”; break;
800         case 2: sport->name = “STUART”; break;
801         case 3: sport->name = “HWUART”; break;
802         default:
803                 sport->name = “???”;
804                 break;
805         }
806         
807         
808         sport->port.membase = ioremap(mmres->start, mmres->end – mmres->start + 1);
809         if (!sport->port.membase) {
810                 ret = -ENOMEM;
811                 goto err_clk;
812         }
813
814         serial_pxa_ports[dev->id] = sport;
815
816         uart_add_one_port(&serial_pxa_reg, &sport->port);
817         platform_set_drvdata(dev, sport);
818         return 0;
819
820  err_clk:
821         clk_put(sport->clk);
822  err_free:
823         kfree(sport);
824         return ret;
825 }
整个probe函数的功能就是配置一个port,并将其加入到系统中。从其参数来看,其仅仅是针对一个设备进行操作。那么,便会产生一个问题:如果系统中有多个相同的设备,该如何去驱动每一个设备?
回答这个问题,仅仅从该probe函数本身是无法得到的,因为从它的参数就可以看出,它仅仅用来probe 一个设备的。
顺藤摸瓜,往上层看究竟
任何一个模块,在被调用的时候,最先执行的是module_init(fn). module_init是一个宏。其最终要执行其参数:fn。仍旧以PXA688的UART为例,它的module_init,以及fn为:
drivers/tty/serial/pxa.c
853 int __init serial_pxa_init(void)
854 {
855         int ret;
856
857         ret = uart_register_driver(&serial_pxa_reg);
858         if (ret != 0)
859                 return ret;
860
861         ret = platform_driver_register(&serial_pxa_driver);
862         if (ret != 0)
863                 uart_unregister_driver(&serial_pxa_reg);
864
865         return ret;
866 }
874 module_init(serial_pxa_init);
对于该例,由于其为uart模块(不光要向kernel注册为字符设备,还要向tty framework注册)。所以,它的init函数:serial_pxa_init 稍微繁琐一些,不光要向platform类总线register driver:861行的platform_driver_register,还要向上层tty core以及 kernel做一些注册工作:857行的uart_register_driver。
我们只关注861行的platform_driver_register。以它为脉,可以回答上面提出的问题。
 433 /**
 434  * platform_driver_register – register a driver for platform-level devices
 435  * @drv: platform driver structure
 436  */
 437 int platform_driver_register(struct platform_driver *drv)
 438 {
 439         drv->driver.bus = &platform_bus_type;
 440         if (drv->probe)
 441                 drv->driver.probe = platform_drv_probe;
 442         if (drv->remove)
 443                 drv->driver.remove = platform_drv_remove;
 444         if (drv->shutdown)
 445                 drv->driver.shutdown = platform_drv_shutdown;
 446
 447         return driver_register(&drv->driver);
 448 }
从439行,我们可以看出其bus的类型:platform_bus_type–是Kernel为了方便管理各种Misc设备,虚拟出来的总线,在hardware platform中是没有的。
440~446,是一些赋值操作,直接无视。
从447行,往下继续看:
platform_driver_register->driver_register:
218  * We pass off most of the work to the bus_add_driver() call,
219  * since most of the things we have to do deal with the bus
220  * structures.
221  */
222 int driver_register(struct device_driver *drv)
223 {
224         int ret;
225         struct device_driver *other;
226
227         BUG_ON(!drv->bus->p);
228
229         if ((drv->bus->probe && drv->probe) ||
230             (drv->bus->remove && drv->remove) ||
231             (drv->bus->shutdown && drv->shutdown))
232                 printk(KERN_WARNING “Driver ‘%s’ needs updating – please use “
233                         “bus_type methodsn”, drv->name);
234
235         other = driver_find(drv->name, drv->bus);
236         if (other) {
237                 put_driver(other);
238                 printk(KERN_ERR “Error: Driver ‘%s’ is already registered, “
239                         “aborting…n”, drv->name);
240                 return -EBUSY;
241         }
242
243         ret = bus_add_driver(drv);
244         if (ret)
245                 return ret;
246         ret = driver_add_groups(drv, drv->groups);
247         if (ret)
248                 bus_remove_driver(drv);
249         return ret;
250 }
228~221行中的注释告诉我们,要看看243行,因此从243行继续tracking,其余行无视。
platform_driver_register->driver_register->bus_add_driver:
 625 int bus_add_driver(struct device_driver *drv)
 626 {
                …
 650         if (drv->bus->p->drivers_autoprobe) {
 651                 error = driver_attach(drv);
 652                 if (error)
 653                         goto out_unregister;
 654         }
 655         klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
 656         module_add_driver(drv->owner, drv);
                …
 689 }
对于platform_bus_type总线,其650行是true,所以track第651行:
platform_driver_register->driver_register->bus_add_driver->driver_attach
301 /**
302  * driver_attach – try to bind driver to devices.
303  * @drv: driver.
304  *
305  * Walk the list of devices that the bus has on it and try to
306  * match the driver with each one.  If driver_probe_device()
307  * returns 0 and the @dev->driver is set, we’ve found a
308  * compatible pair.
309  */
310 int driver_attach(struct device_driver *drv)
311 {
312         return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
313 }
305行和309行的注释说:它会遍历总线上的所有设备,去进行__driver_attach式匹配。
312行的bus_for_each_dev是一个宏,具体的功能是对bus上的设备链表进行遍历,并将驱动drv和每一个设备进行__driver_attach。那么__driver_attach到底干什么的? 当然不会是针对每一个设备都attach这个驱动了^_^!
platform_driver_register->driver_register->bus_add_driver->driver_attach->__driver_attach:
272 static int __driver_attach(struct device *dev, void *data)
273 {
274         struct device_driver *drv = data;
275
276         /*
277          * Lock device and try to bind to it. We drop the error
278          * here and always return 0, because we need to keep trying
279          * to bind to devices and some drivers will return an error
280          * simply if it didn’t support the device.
281          *
282          * driver_probe_device() will spit a warning if there
283          * is an error.
284          */
285
286         if (!driver_match_device(drv, dev))
287                 return 0;
288
289         if (dev->parent)        /* Needed for USB */
290                 device_lock(dev->parent);
291         device_lock(dev);
292         if (!dev->driver)
293                 driver_probe_device(drv, dev);
294         device_unlock(dev);
295         if (dev->parent)
296                 device_unlock(dev->parent);
297
298         return 0;
299 }
286~287是一个判断。这个判断调用driver_match_device,只有一行语句:
{ return drv->bus->match ? drv->bus->match(dev, drv) : 1;}
如果drv->bus->match非0,返回drv->bus->match(dev,drv),否则返回1。返回1,就意味着 __driver_attach执行到287行就return了。而该uart驱动所挂在的platform_bus_type总线当然是有match了(如果没有实现match,那驱动无论如何都找不到对应的设备了。^_^)
其bus的match函数的功能:platform_match
 627 static int platform_match(struct device *dev, struct device_driver *drv)
 628 {
 629         struct platform_device *pdev = to_platform_device(dev);
 630         struct platform_driver *pdrv = to_platform_driver(drv);
。。。
 641         return (strcmp(pdev->name, drv->name) == 0);
 642 }
也很简单,只是比对名字而已。如果设备的名字和驱动的名字配对成功了,那就说明驱动要加载了。
所以,如果驱动找到了设备,那么就会在293行中调用driver_probe_device:
platform_driver_register->driver_register->bus_add_driver->driver_attach->__driver_attach->driver_probe_device:
200 int driver_probe_device(struct device_driver *drv, struct device *dev)
201 {
202         int ret = 0;
203
204         if (!device_is_registered(dev))
205                 return -ENODEV;
206
207         printk(“bus: ‘%s': %s: matched device %s with driver %sn”,
208                  drv->bus->name, __func__, dev_name(dev), drv->name);
209
210         pm_runtime_get_noresume(dev);
211         pm_runtime_barrier(dev);
212         ret = really_probe(dev, drv);
213         pm_runtime_put_sync(dev);
214
215         return ret;
216 }
只看212行,从名字really_probe就能看到,真正驱动的probe函数要现身了。
platform_driver_register->driver_register->bus_add_driver->driver_attach->__driver_attach->driver_probe_device->really_probe:
108 static int really_probe(struct device *dev, struct device_driver *drv)
109 {
110         int ret = 0;
123
124         if (dev->bus->probe) {
125                 ret = dev->bus->probe(dev);
126                 if (ret)
127                         goto probe_failed;
128         } else if (drv->probe) {
129                 ret = drv->probe(dev);
130                 if (ret)
131                         goto probe_failed;
132         }
}
OK,第129行是真正要用到serial_pxa_probe,开始针对每一个port进行初始化和注册了。
在这个routine中,bus_for_each_dev宏是个关键。它会遍历bus上的每一个设备,只要名字匹配,就会调用驱动的probe对硬件进行初始化和注册。

From Li Haifeng's Blog, post 关于Probe分析

Post Footer automatically generated by wp-posturl plugin for wordpress.

分享到: