platform device和driver之间的关系

platform device和driver之间的关系[c-sharp] viewplaincopy内核中的platform driver机制需要将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform device提供的标准接口进行申请并使用。这样可以提高驱动和资源管理的独立性。本文的目的就是希望弄清楚platform device和driver之间的关系。  1.1

大家好,又见面了,我是你们的朋友全栈君。

[c-sharp] 
view plain
copy

  1. 内核中的platform driver机制需要将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform device提供的标准接口进行申请并使用。这样可以提高驱动和资源管理的独立性。本文的目的就是希望弄清楚platform device和driver之间的关系。  
  2. 1.1    相关数据结构  
  3. 1.1.1   device  
  4. 这个结构体定义为:  
  5. struct device {  
  6.      struct klist       klist_children;  
  7.      struct klist_node  knode_parent;      /* node in sibling list */  
  8.      struct klist_node  knode_driver;  
  9.      struct klist_node  knode_bus;  
  10.      struct device      *parent;  
  11.    
  12.      struct kobject kobj;  
  13.      char bus_id[BUS_ID_SIZE];   /* position on parent bus */  
  14.      struct device_type *type;  
  15.      unsigned      is_registered:1;  
  16.      unsigned      uevent_suppress:1;  
  17.      struct device_attribute uevent_attr;  
  18.      struct device_attribute *devt_attr;  
  19.    
  20.      struct semaphore   sem; /* semaphore to synchronize calls to 
  21.                         * its driver. 
  22.                         */  
  23.    
  24.      struct bus_type    * bus;        /* type of bus device is on */  
  25.      struct device_driver *driver;    /* which driver has allocated this 
  26.                           device */  
  27.      void     *driver_data; /* data private to the driver */  
  28.      void     *platform_data;    /* Platform specific data, device 
  29.                           core doesn’t touch it */  
  30.      struct dev_pm_info power;  
  31.   
  32. #ifdef CONFIG_NUMA  
  33.      int      numa_node;    /* NUMA node this device is close to */  
  34. #endif  
  35.      u64      *dma_mask;    /* dma mask (if dma’able device) */  
  36.      u64      coherent_dma_mask;/* Like dma_mask, but for 
  37.                             alloc_coherent mappings as 
  38.                             not all hardware supports 
  39.                             64 bit addresses for consistent 
  40.                             allocations such descriptors. */  
  41.    
  42.      struct list_head   dma_pools;    /* dma pools (if dma’ble) */  
  43.    
  44.      struct dma_coherent_mem *dma_mem; /* internal for coherent mem 
  45.                             override */  
  46.      /* arch specific additions */  
  47.      struct dev_archdata    archdata;  
  48.    
  49.      spinlock_t         devres_lock;  
  50.      struct list_head   devres_head;  
  51.    
  52.      /* class_device migration path */  
  53.      struct list_head   node;  
  54.      struct class       *class;  
  55.      dev_t              devt;         /* dev_t, creates the sysfs “dev” */  
  56.      struct attribute_group **groups; /* optional groups */  
  57.    
  58.      void (*release)(struct device * dev);  
  59. };  
  60. 这个结构体有点复杂,不过我们暂时用不了这么多。  
  61.    
  62.    
  63.    
  64. 1.1.2   resource  
  65. 这个结构体定义为:  
  66. /* 
  67.  * Resources are tree-like, allowing 
  68.  * nesting etc.. 
  69.  */  
  70. struct resource {  
  71.      resource_size_t start;  
  72.      resource_size_t end;  
  73.      const char *name;  
  74.      unsigned long flags;  
  75.      struct resource *parent, *sibling, *child;  
  76. };  
  77. 在这个结构体中,start和end的意义将根据flags中指定的资源类型进行解释。内核对资源进行了分类,一共有四种类型:  
  78. #define IORESOURCE_IO       0x00000100    /* Resource type */  
  79. #define IORESOURCE_MEM      0x00000200  
  80. #define IORESOURCE_IRQ      0x00000400  
  81. #define IORESOURCE_DMA      0x00000800  
  82. 对于DM9000来说,其定义的资源如下:  
  83. static struct resource dm9000_bfin_resources[] = {  
  84.      {  
  85.          .start = 0x2C000000,  
  86.          .end = 0x2C000000 + 0x7F,  
  87.          .flags = IORESOURCE_MEM,  
  88.      }, {  
  89.          .start = IRQ_PF10,  
  90.          .end = IRQ_PF10,  
  91.          .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,  
  92.      },  
  93. };  
  94. 也就是说,它定义了两种类型的资源。从这里也可以看出resource结构体里面的name成员没有太大的用处。  
  95.    
  96. 1.1.3   platform_device  
  97. 这个结构体定义为:  
  98. struct platform_device {  
  99.      const char    * name;  
  100.      u32      id;  
  101.      struct device dev;  
  102.      u32      num_resources;  
  103.      struct resource    * resource;  
  104. };  
  105. 它对device加了一层包装,添加了resource的内容。看看DM9000的定义:  
  106. static struct platform_device dm9000_bfin_device = {  
  107.      .name = “dm9000”,  
  108.      .id = -1,  
  109.      .num_resources = ARRAY_SIZE(dm9000_bfin_resources),  
  110.      .resource = dm9000_bfin_resources,  
  111. };  
  112. 注意这里的name。  
  113. 1.1.4   device_driver  
  114. 这个结构体定义为:  
  115. struct device_driver {  
  116.      const char         * name;  
  117.      struct bus_type        * bus;  
  118.    
  119.      struct kobject         kobj;  
  120.      struct klist       klist_devices;  
  121.      struct klist_node  knode_bus;  
  122.    
  123.      struct module      * owner;  
  124.      const char         * mod_name;   /* used for built-in modules */  
  125.      struct module_kobject  * mkobj;  
  126.    
  127.      int  (*probe) (struct device * dev);  
  128.      int  (*remove) (struct device * dev);  
  129.      void (*shutdown)   (struct device * dev);  
  130.      int  (*suspend)    (struct device * dev, pm_message_t state);  
  131.      int  (*resume) (struct device * dev);  
  132. };  
  133.    
  134.    
  135. 1.1.5   platform_driver  
  136. 这个结构体定义为:  
  137. struct platform_driver {  
  138.      int (*probe)(struct platform_device *);  
  139.      int (*remove)(struct platform_device *);  
  140.      void (*shutdown)(struct platform_device *);  
  141.      int (*suspend)(struct platform_device *, pm_message_t state);  
  142.      int (*suspend_late)(struct platform_device *, pm_message_t state);  
  143.      int (*resume_early)(struct platform_device *);  
  144.      int (*resume)(struct platform_device *);  
  145.      struct device_driver driver;  
  146. };  
  147. 它在device_driver的基础上封装了几个操作函数。  
  148. 1.1.6   bus_type  
  149. 这个结构体定义为:  
  150. struct bus_type {  
  151.      const char         * name;  
  152.      struct module      * owner;  
  153.    
  154.      struct kset        subsys;  
  155.      struct kset        drivers;  
  156.      struct kset        devices;  
  157.      struct klist       klist_devices;  
  158.      struct klist       klist_drivers;  
  159.    
  160.      struct blocking_notifier_head bus_notifier;  
  161.    
  162.      struct bus_attribute   * bus_attrs;  
  163.      struct device_attribute * dev_attrs;  
  164.      struct driver_attribute * drv_attrs;  
  165.      struct bus_attribute drivers_autoprobe_attr;  
  166.      struct bus_attribute drivers_probe_attr;  
  167.    
  168.      int      (*match)(struct device * dev, struct device_driver * drv);  
  169.      int      (*uevent)(struct device *dev, char **envp,  
  170.                      int num_envp, char *buffer, int buffer_size);  
  171.      int      (*probe)(struct device * dev);  
  172.      int      (*remove)(struct device * dev);  
  173.      void     (*shutdown)(struct device * dev);  
  174.    
  175.      int (*suspend)(struct device * dev, pm_message_t state);  
  176.      int (*suspend_late)(struct device * dev, pm_message_t state);  
  177.      int (*resume_early)(struct device * dev);  
  178.      int (*resume)(struct device * dev);  
  179.    
  180.      unsigned int drivers_autoprobe:1;  
  181. };  
  182.    
  183.    
  184.    
  185. 1.2    资源注册  
  186. 在arch/blackfin/mach-bf561/boards/ezkit.c中有这样的代码:  
  187. static int __init ezkit_init(void)  
  188. {  
  189.      int ret;  
  190.    
  191.      printk(KERN_INFO “%s(): registering device resources/n”, __func__);  
  192.    
  193.      ret = platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));  
  194.      if (ret < 0)  
  195.          return ret;  
  196.    
  197.      return 0;  
  198. }  
  199.    
  200. arch_initcall(ezkit_init);  
  201. 这里使用了arch_initcall来对ezkit_init函数进行调用次序的限制,而驱动的加载通常是使用module_init进行限制的,因此ezkit_init函数将先于驱动加载。  
  202. 在这里ezkit_devices的定义为:  
  203. static struct platform_device *ezkit_devices[] __initdata = {  
  204.      &dm9000_bfin_device,  
  205. …………  
  206. };  
  207. 1.2.1   platform_add_devices  
  208. 这个函数比较简单:  
  209. /** 
  210.  *   platform_add_devices – add a numbers of platform devices 
  211.  *   @devs: array of platform devices to add 
  212.  *   @num: number of platform devices in array 
  213.  */  
  214. int platform_add_devices(struct platform_device **devs, int num)  
  215. {  
  216.      int i, ret = 0;  
  217.    
  218.      for (i = 0; i < num; i++) {  
  219.          ret = platform_device_register(devs[i]);  
  220.          if (ret) {  
  221.               while (–i >= 0)  
  222.                    platform_device_unregister(devs[i]);  
  223.               break;  
  224.          }  
  225.      }  
  226.    
  227.      return ret;  
  228. }  
  229. 为这个数组中的每个元素调用platform_device_register,如果出错则注销此前注册的所有platform device。  
  230. 1.2.2   platform_device_register  
  231. 这个函数的实现为:  
  232. /** 
  233.  *   platform_device_register – add a platform-level device 
  234.  *   @pdev:   platform device we’re adding 
  235.  * 
  236.  */  
  237. int platform_device_register(struct platform_device * pdev)  
  238. {  
  239.      device_initialize(&pdev->dev);  
  240.      return platform_device_add(pdev);  
  241. }  
  242. 也比较简单,先调用device_initialize初始化platform_device::dev,这里仅仅是对device结构体的成员赋初值,略过它不做分析。接下来的关键是platform_device_add。  
  243. 1.2.3   platform_device_add  
  244. 这个函数定义为:  
  245. /** 
  246.  *   platform_device_add – add a platform device to device hierarchy 
  247.  *   @pdev:   platform device we’re adding 
  248.  * 
  249.  *   This is part 2 of platform_device_register(), though may be called 
  250.  *   separately _iff_ pdev was allocated by platform_device_alloc(). 
  251.  */  
  252. int platform_device_add(struct platform_device *pdev)  
  253. {  
  254.      int i, ret = 0;  
  255.    
  256.      if (!pdev)  
  257.           return -EINVAL;  
  258.    
  259.      if (!pdev->dev.parent)  
  260.          pdev->dev.parent = &platform_bus;  
  261.    
  262.      pdev->dev.bus = &platform_bus_type;  
  263.    
  264.      if (pdev->id != -1)  
  265.          snprintf(pdev->dev.bus_id, BUS_ID_SIZE, “%s.%u”, pdev->name, pdev->id);  
  266.      else  
  267.          strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);  
  268.    
  269.      for (i = 0; i < pdev->num_resources; i++) {  
  270.          struct resource *p, *r = &pdev->resource[i];  
  271.    
  272.          if (r->name == NULL)  
  273.               r->name = pdev->dev.bus_id;  
  274.    
  275.          p = r->parent;  
  276.          if (!p) {  
  277.               if (r->flags & IORESOURCE_MEM)  
  278.                    p = &iomem_resource;  
  279.               else if (r->flags & IORESOURCE_IO)  
  280.                    p = &ioport_resource;  
  281.          }  
  282.    
  283.          if (p && insert_resource(p, r)) {  
  284.               printk(KERN_ERR  
  285.                      “%s: failed to claim resource %d/n”,  
  286.                      pdev->dev.bus_id, i);  
  287.               ret = -EBUSY;  
  288.               goto failed;  
  289.          }  
  290.      }  
  291.    
  292.      pr_debug(“Registering platform device ‘%s’. Parent at %s/n”,  
  293.           pdev->dev.bus_id, pdev->dev.parent->bus_id);  
  294.    
  295.      ret = device_add(&pdev->dev);  
  296.      if (ret == 0)  
  297.          return ret;  
  298.    
  299.  failed:  
  300.      while (–i >= 0)  
  301.          if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))  
  302.               release_resource(&pdev->resource[i]);  
  303.      return ret;  
  304. }  
  305. 在这个函数里做了两件关键的事情,一个是注册device设备,它将device::bus指定为platform_bus_type。另一个是注册resource。看下面的这几行代码:  
  306.          if (!p) {  
  307.               if (r->flags & IORESOURCE_MEM)  
  308.                    p = &iomem_resource;  
  309.               else if (r->flags & IORESOURCE_IO)  
  310.                    p = &ioport_resource;  
  311.          }  
  312. 对照DM9000的资源定义:  
  313. static struct resource dm9000_bfin_resources[] = {  
  314.      {  
  315.          .start = 0x2C000000,  
  316.          .end = 0x2C000000 + 0x7F,  
  317.          .flags = IORESOURCE_MEM,  
  318.      }, {  
  319.          .start = IRQ_PF10,  
  320.          .end = IRQ_PF10,  
  321.          .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,  
  322.      },  
  323. };  
  324. 它的中断资源并没有进行注册。  
  325. 1.2.4   device_add  
  326. 这一函数定义为:  
  327. /** 
  328.  *   device_add – add device to device hierarchy. 
  329.  *   @dev:    device. 
  330.  * 
  331.  *   This is part 2 of device_register(), though may be called 
  332.  *   separately _iff_ device_initialize() has been called separately. 
  333.  * 
  334.  *   This adds it to the kobject hierarchy via kobject_add(), adds it 
  335.  *   to the global and sibling lists for the device, then 
  336.  *   adds it to the other relevant subsystems of the driver model. 
  337.  */  
  338. int device_add(struct device *dev)  
  339. {  
  340. ……………………..  
  341.    
  342.      if ((error = device_add_attrs(dev)))  
  343.          goto AttrsError;  
  344.      if ((error = device_pm_add(dev)))  
  345.          goto PMError;  
  346.      if ((error = bus_add_device(dev)))  
  347.          goto BusError;  
  348. …………………..  
  349. }  
  350. 这里有一个关键调用bus_add_device,它将把dev添加到platform_bus_type这一全局变量中的列表。  
  351. 1.2.5   bus_add_device  
  352. 这个函数定义为:  
  353. /** 
  354.  *   bus_add_device – add device to bus 
  355.  *   @dev:    device being added 
  356.  * 
  357.  *   – Add the device to its bus’s list of devices. 
  358.  *   – Create link to device’s bus. 
  359.  */  
  360. int bus_add_device(struct device * dev)  
  361. {  
  362.      struct bus_type * bus = get_bus(dev->bus);  
  363.      int error = 0;  
  364.    
  365.      if (bus) {  
  366.          pr_debug(“bus %s: add device %s/n”, bus->name, dev->bus_id);  
  367.          error = device_add_attrs(bus, dev);  
  368.          if (error)  
  369.               goto out_put;  
  370.          error = sysfs_create_link(&bus->devices.kobj,  
  371.                             &dev->kobj, dev->bus_id);  
  372.          if (error)  
  373.               goto out_id;  
  374.          error = sysfs_create_link(&dev->kobj,  
  375.                    &dev->bus->subsys.kobj, “subsystem”);  
  376.          if (error)  
  377.               goto out_subsys;  
  378.          error = make_deprecated_bus_links(dev);  
  379.          if (error)  
  380.               goto out_deprecated;  
  381.      }  
  382.      return 0;  
  383.    
  384. out_deprecated:  
  385.      sysfs_remove_link(&dev->kobj, “subsystem”);  
  386. out_subsys:  
  387.      sysfs_remove_link(&bus->devices.kobj, dev->bus_id);  
  388. out_id:  
  389.      device_remove_attrs(bus, dev);  
  390. out_put:  
  391.      put_bus(dev->bus);  
  392.      return error;  
  393. }  
  394. 注意当执行到此函数时dev->bus指向platform_bus_type这一全局变量,因而这一函数将把dev添加到platform_bus_type的链表中。  
  395.    
  396.    
  397. 1.3    驱动注册  
  398. 下面是DM9000网卡的驱动加载代码:  
  399. static int __init  
  400. dm9000_init(void)  
  401. {  
  402.      printk(KERN_INFO “%s Ethernet Driver/n”, CARDNAME);  
  403.    
  404.      return platform_driver_register(&dm9000_driver);   /* search board and register */  
  405. }  
  406. module_init(dm9000_init);  
  407. 很简单的代码,直接调用platform_driver_register注册驱动,这里dm9000_driver的定义为:  
  408. static struct platform_driver dm9000_driver = {  
  409.      .driver  = {  
  410.          .name    = “dm9000”,  
  411.          .owner   = THIS_MODULE,  
  412.      },  
  413.      .probe   = dm9000_probe,  
  414.      .remove  = dm9000_drv_remove,  
  415.      .suspend = dm9000_drv_suspend,  
  416.      .resume  = dm9000_drv_resume,  
  417. };  
  418.    
  419. 1.3.1   platform_driver_register  
  420. 这个函数定义为:  
  421. /** 
  422.  *   platform_driver_register 
  423.  *   @drv: platform driver structure 
  424.  */  
  425. int platform_driver_register(struct platform_driver *drv)  
  426. {  
  427.      drv->driver.bus = &platform_bus_type;  
  428.      if (drv->probe)  
  429.          drv->driver.probe = platform_drv_probe;  
  430.      if (drv->remove)  
  431.          drv->driver.remove = platform_drv_remove;  
  432.      if (drv->shutdown)  
  433.          drv->driver.shutdown = platform_drv_shutdown;  
  434.      if (drv->suspend)  
  435.          drv->driver.suspend = platform_drv_suspend;  
  436.      if (drv->resume)  
  437.          drv->driver.resume = platform_drv_resume;  
  438.      return driver_register(&drv->driver);  
  439. }  
  440. 注意由于DM9000的platform_driver中指定了probe,remove,suspend,resume这四个函数,因此device_driver结构体中的这几个函数指针将进行初始化设置。最后再调用driver_register注册driver成员,有点奇怪,怎么就抛弃了platform_driver呢?  
  441. 1.3.2   driver_register  
  442. 这个函数定义为:  
  443. /** 
  444.  *   driver_register – register driver with bus 
  445.  *   @drv:    driver to register 
  446.  * 
  447.  *   We pass off most of the work to the bus_add_driver() call, 
  448.  *   since most of the things we have to do deal with the bus 
  449.  *   structures. 
  450.  */  
  451. int driver_register(struct device_driver * drv)  
  452. {  
  453.      if ((drv->bus->probe && drv->probe) ||  
  454.          (drv->bus->remove && drv->remove) ||  
  455.          (drv->bus->shutdown && drv->shutdown)) {  
  456.          printk(KERN_WARNING “Driver ‘%s’ needs updating – please use bus_type methods/n”, drv->name);  
  457.      }  
  458.      klist_init(&drv->klist_devices, NULL, NULL);  
  459.      return bus_add_driver(drv);  
  460. }  
  461. 当函数执行到这里的时候,drv->bus指向的是platform_bus_type这一全局变量。  
  462. struct bus_type platform_bus_type = {  
  463.      .name         = “platform”,  
  464.      .dev_attrs    = platform_dev_attrs,  
  465.      .match        = platform_match,  
  466.      .uevent       = platform_uevent,  
  467.      .suspend = platform_suspend,  
  468.      .suspend_late = platform_suspend_late,  
  469.      .resume_early = platform_resume_early,  
  470.      .resume       = platform_resume,  
  471. };  
  472.    
  473. 1.3.3   bus_add_driver  
  474. 这个函数定义为:  
  475. /** 
  476.  *   bus_add_driver – Add a driver to the bus. 
  477.  *   @drv:    driver. 
  478.  * 
  479.  */  
  480. int bus_add_driver(struct device_driver *drv)  
  481. {  
  482.      struct bus_type * bus = get_bus(drv->bus);  
  483.      int error = 0;  
  484.    
  485.      if (!bus)  
  486.          return -EINVAL;  
  487.    
  488.      pr_debug(“bus %s: add driver %s/n”, bus->name, drv->name);  
  489.      error = kobject_set_name(&drv->kobj, “%s”, drv->name);  
  490.      if (error)  
  491.          goto out_put_bus;  
  492.      drv->kobj.kset = &bus->drivers;  
  493.      if ((error = kobject_register(&drv->kobj)))  
  494.          goto out_put_bus;  
  495.    
  496.      if (drv->bus->drivers_autoprobe) {  
  497.          error = driver_attach(drv);  
  498.          if (error)  
  499.               goto out_unregister;  
  500.      }  
  501.      klist_add_tail(&drv->knode_bus, &bus->klist_drivers);  
  502.      module_add_driver(drv->owner, drv);  
  503.    
  504.      error = driver_add_attrs(bus, drv);  
  505.      if (error) {  
  506.          /* How the hell do we get out of this pickle? Give up */  
  507.          printk(KERN_ERR “%s: driver_add_attrs(%s) failed/n”,  
  508.               __FUNCTION__, drv->name);  
  509.      }  
  510.      error = add_bind_files(drv);  
  511.      if (error) {  
  512.          /* Ditto */  
  513.          printk(KERN_ERR “%s: add_bind_files(%s) failed/n”,  
  514.               __FUNCTION__, drv->name);  
  515.      }  
  516.    
  517.      return error;  
  518. out_unregister:  
  519.      kobject_unregister(&drv->kobj);  
  520. out_put_bus:  
  521.      put_bus(bus);  
  522.      return error;  
  523. }  
  524. 当函数执行到此的时候,drv->bus将指向platform_bus_type这一全局变量,而这一全局变量的drivers_autoprobe成员在bus_register这一全局初始化函数中设置为1。因此这里将调用driver_attach函数,注意此时传递进去的参数drv指向的是dm9000_driver的driver成员。  
  525. 1.3.4   driver_attach  
  526. 这一函数定义为:  
  527. /** 
  528.  *   driver_attach – try to bind driver to devices. 
  529.  *   @drv:    driver. 
  530.  * 
  531.  *   Walk the list of devices that the bus has on it and try to 
  532.  *   match the driver with each one.  If driver_probe_device() 
  533.  *   returns 0 and the @dev->driver is set, we’ve found a 
  534.  *   compatible pair. 
  535.  */  
  536. int driver_attach(struct device_driver * drv)  
  537. {  
  538.      return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);  
  539. }  
  540. 很简单,转向bus_for_each_dev。  
  541. 1.3.5   bus_for_each_dev  
  542. 这一函数定义为:  
  543. /** 
  544.  *   bus_for_each_dev – device iterator. 
  545.  *   @bus:    bus type. 
  546.  *   @start:  device to start iterating from. 
  547.  *   @data:   data for the callback. 
  548.  *   @fn: function to be called for each device. 
  549.  * 
  550.  *   Iterate over @bus’s list of devices, and call @fn for each, 
  551.  *   passing it @data. If @start is not NULL, we use that device to 
  552.  *   begin iterating from. 
  553.  * 
  554.  *   We check the return of @fn each time. If it returns anything 
  555.  *   other than 0, we break out and return that value. 
  556.  * 
  557.  *   NOTE: The device that returns a non-zero value is not retained 
  558.  *   in any way, nor is its refcount incremented. If the caller needs 
  559.  *   to retain this data, it should do, and increment the reference 
  560.  *   count in the supplied callback. 
  561.  */  
  562.    
  563. int bus_for_each_dev(struct bus_type * bus, struct device * start,  
  564.               void * data, int (*fn)(struct device *, void *))  
  565. {  
  566.      struct klist_iter i;  
  567.      struct device * dev;  
  568.      int error = 0;  
  569.    
  570.      if (!bus)  
  571.          return -EINVAL;  
  572.    
  573.      klist_iter_init_node(&bus->klist_devices, &i,  
  574.                    (start ? &start->knode_bus : NULL));  
  575.      while ((dev = next_device(&i)) && !error)  
  576.          error = fn(dev, data);  
  577.      klist_iter_exit(&i);  
  578.      return error;  
  579. }  
  580. 简单枚举此总线上注册的device,然后为其调用__driver_attach函数,试图将一个device和传递进来的driver相匹配。  
  581. 1.3.6   __driver_attach  
  582. 这一函数定义为:  
  583. static int __driver_attach(struct device * dev, void * data)  
  584. {  
  585.      struct device_driver * drv = data;  
  586.    
  587.      /* 
  588.       * Lock device and try to bind to it. We drop the error 
  589.       * here and always return 0, because we need to keep trying 
  590.       * to bind to devices and some drivers will return an error 
  591.       * simply if it didn’t support the device. 
  592.       * 
  593.       * driver_probe_device() will spit a warning if there 
  594.       * is an error. 
  595.       */  
  596.    
  597.      if (dev->parent)   /* Needed for USB */  
  598.          down(&dev->parent->sem);  
  599.      down(&dev->sem);  
  600.      if (!dev->driver)  
  601.          driver_probe_device(drv, dev);  
  602.      up(&dev->sem);  
  603.      if (dev->parent)  
  604.          up(&dev->parent->sem);  
  605.    
  606.      return 0;  
  607. }  
  608. 很简单,转而调用driver_probe_device进行驱动的匹配。  
  609. 1.3.7   driver_probe_device  
  610. 这个函数定义为:  
  611. /** 
  612.  * driver_probe_device – attempt to bind device & driver together 
  613.  * @drv: driver to bind a device to 
  614.  * @dev: device to try to bind to the driver 
  615.  * 
  616.  * First, we call the bus’s match function, if one present, which should 
  617.  * compare the device IDs the driver supports with the device IDs of the 
  618.  * device. Note we don’t do this ourselves because we don’t know the 
  619.  * format of the ID structures, nor what is to be considered a match and 
  620.  * what is not. 
  621.  * 
  622.  * This function returns 1 if a match is found, -ENODEV if the device is 
  623.  * not registered, and 0 otherwise. 
  624.  * 
  625.  * This function must be called with @dev->sem held.  When called for a 
  626.  * USB interface, @dev->parent->sem must be held as well. 
  627.  */  
  628. int driver_probe_device(struct device_driver * drv, struct device * dev)  
  629. {  
  630.      int ret = 0;  
  631.    
  632.      if (!device_is_registered(dev))  
  633.          return -ENODEV;  
  634.      if (drv->bus->match && !drv->bus->match(dev, drv))  
  635.          goto done;  
  636.    
  637.      pr_debug(“%s: Matched Device %s with Driver %s/n”,  
  638.           drv->bus->name, dev->bus_id, drv->name);  
  639.    
  640.      ret = really_probe(dev, drv);  
  641.    
  642. done:  
  643.      return ret;  
  644. }  
  645. 此时的drv->bus指向platform_bus_type这一全局变量,而它的match函数为platform_match,且让我们看看它是如何确定device和driver是否匹配的。  
  646. /** 
  647.  *   platform_match – bind platform device to platform driver. 
  648.  *   @dev:    device. 
  649.  *   @drv:    driver. 
  650.  * 
  651.  *   Platform device IDs are assumed to be encoded like this: 
  652.  *   “<name><instance>”, where <name> is a short description of the 
  653.  *   type of device, like “pci” or “floppy”, and <instance> is the 
  654.  *   enumerated instance of the device, like ‘0’ or ’42’. 
  655.  *   Driver IDs are simply “<name>”. 
  656.  *   So, extract the <name> from the platform_device structure, 
  657.  *   and compare it against the name of the driver. Return whether 
  658.  *   they match or not. 
  659.  */  
  660.    
  661. static int platform_match(struct device * dev, struct device_driver * drv)  
  662. {  
  663.      struct platform_device *pdev = container_of(dev, struct platform_device, dev);  
  664.    
  665.      return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);  
  666. }  
  667. 也就是说,它通过比较pdev->name和drv->name是否匹配来决定。  
  668. 对于DM9000的驱动来说,这里的pdev指向dm9000_bfin_device,看看它的初始值:  
  669. static struct platform_device dm9000_bfin_device = {  
  670.      .name = “dm9000”,  
  671.      .id = -1,  
  672.      .num_resources = ARRAY_SIZE(dm9000_bfin_resources),  
  673.      .resource = dm9000_bfin_resources,  
  674. };  
  675. 再看drv,其指向dm9000_driver这一变量中的driver成员。  
  676. static struct platform_driver dm9000_driver = {  
  677.      .driver  = {  
  678.          .name    = “dm9000”,  
  679.          .owner   = THIS_MODULE,  
  680.      },  
  681.      .probe   = dm9000_probe,  
  682.      .remove  = dm9000_drv_remove,  
  683.      .suspend = dm9000_drv_suspend,  
  684.      .resume  = dm9000_drv_resume,  
  685. };  
  686. 在进行了正确的名称匹配之后,将调用really_probe进行硬件检测。  
  687. 1.3.8   really_probe  
  688. 这一函数定义为:  
  689. static int really_probe(struct device *dev, struct device_driver *drv)  
  690. {  
  691.      int ret = 0;  
  692.    
  693.      atomic_inc(&probe_count);  
  694.      pr_debug(“%s: Probing driver %s with device %s/n”,  
  695.           drv->bus->name, drv->name, dev->bus_id);  
  696.      WARN_ON(!list_empty(&dev->devres_head));  
  697.    
  698.      dev->driver = drv;  
  699.      if (driver_sysfs_add(dev)) {  
  700.          printk(KERN_ERR “%s: driver_sysfs_add(%s) failed/n”,  
  701.               __FUNCTION__, dev->bus_id);  
  702.          goto probe_failed;  
  703.      }  
  704.    
  705.      if (dev->bus->probe) {  
  706.          ret = dev->bus->probe(dev);  
  707.          if (ret)  
  708.               goto probe_failed;  
  709.      } else if (drv->probe) {  
  710.          ret = drv->probe(dev);  
  711.          if (ret)  
  712.               goto probe_failed;  
  713.      }  
  714.    
  715.      driver_bound(dev);  
  716.      ret = 1;  
  717.      pr_debug(“%s: Bound Device %s to Driver %s/n”,  
  718.           drv->bus->name, dev->bus_id, drv->name);  
  719.      goto done;  
  720.    
  721. probe_failed:  
  722.      devres_release_all(dev);  
  723.      driver_sysfs_remove(dev);  
  724.      dev->driver = NULL;  
  725.    
  726.      if (ret != -ENODEV && ret != -ENXIO) {  
  727.          /* driver matched but the probe failed */  
  728.          printk(KERN_WARNING  
  729.                 “%s: probe of %s failed with error %d/n”,  
  730.                 drv->name, dev->bus_id, ret);  
  731.      }  
  732.      /* 
  733.       * Ignore errors returned by ->probe so that the next driver can try 
  734.       * its luck. 
  735.       */  
  736.      ret = 0;  
  737. done:  
  738.      atomic_dec(&probe_count);  
  739.      wake_up(&probe_waitqueue);  
  740.      return ret;  
  741. }  
  742. 此时的drv->bus指向platform_bus_type这一全局变量,其probe回调函数没有指定,而drv->probe函数则指向dm9000_probe。因此转向dm9000_probe执行,并将dm9000_bfin_device做为参数传递进去。  
  743. 1.4    结论  
  744. platform device和driver分别向platform_bus_type这一中介注册,并通过名称进行相互间的匹配。很是有点婚姻中介的味道,还有点对暗号的神秘,呵呵! 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163801.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号