linux设备驱动模型之总线、设备、驱动三者的关系

总线、设备、驱动,也就是bus、device、driver,在内核里都有对应的结构体,在include/linux/device.h 里定义。

Device.h (linux-3.4.2\include\linux)

1、总线、设备、驱动三者的关系



2、结构体

(1)总线结构体

[cpp]  view plain  copy
  1. struct bus_type {  
  2.     const char      *name;                                                    /*总线名*/  
  3.     const char      *dev_name;  
  4.     struct device       *dev_root;  
  5.     struct bus_attribute    *bus_attrs;  
  6.     struct device_attribute *dev_attrs;//设备属性  
  7.     struct driver_attribute *drv_attrs;//驱动属性  
  8.   //设备驱动匹配函数  
  9.     int (*match)(struct device *dev, struct device_driver *drv);  
  10.     int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  
  11.     int (*probe)(struct device *dev);  
  12.     int (*remove)(struct device *dev);  
  13.     void (*shutdown)(struct device *dev);  
  14.   
  15.     int (*suspend)(struct device *dev, pm_message_t state);  
  16.     int (*resume)(struct device *dev);  
  17.   
  18.     const struct dev_pm_ops *pm;  
  19.   
  20.     struct iommu_ops *iommu_ops;  
  21.   
  22.     struct subsys_private *p;  
  23. };  

如平台总线

[cpp]  view plain  copy
  1. struct bus_type platform_bus_type = {  
  2.     .name       = "platform",  
  3.     .dev_attrs  = platform_dev_attrs,  
  4.     .match      = platform_match,  
  5.     .uevent     = platform_uevent,  
  6.     .pm     = &platform_dev_pm_ops,  
  7. };  
总线注册:
[cpp]  view plain  copy
  1. #define bus_register(subsys)            \  
  2. ({                      \  
  3.     static struct lock_class_key __key; \  
  4.     __bus_register(subsys, &__key); \  
  5. })  
  6.   
  7.   
  8. int __bus_register(struct bus_type *bus, struct lock_class_key *key)  
  9. {  
  10.     int retval;  
  11.     struct subsys_private *priv;  
  12.   
  13.     priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);  
  14.     if (!priv)  
  15.         return -ENOMEM;  
  16.   
  17.     priv->bus = bus;  
  18.     bus->p = priv;  
  19.   
  20.     BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);  
  21.   
  22.     retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);  
  23.     if (retval)  
  24.         goto out;  
  25.   
  26.     priv->subsys.kobj.kset = bus_kset;  
  27.     priv->subsys.kobj.ktype = &bus_ktype;  
  28.     priv->drivers_autoprobe = 1;  
  29.   
  30.     retval = kset_register(&priv->subsys);  
  31.     if (retval)  
  32.         goto out;  
  33.   
  34.     retval = bus_create_file(bus, &bus_attr_uevent);  
  35.     if (retval)  
  36.         goto bus_uevent_fail;  
  37.   
  38.     priv->devices_kset = kset_create_and_add("devices", NULL,  
  39.                          &priv->subsys.kobj);  
  40.     if (!priv->devices_kset) {  
  41.         retval = -ENOMEM;  
  42.         goto bus_devices_fail;  
  43.     }  
  44.   
  45.     priv->drivers_kset = kset_create_and_add("drivers", NULL,  
  46.                          &priv->subsys.kobj);  
  47.     if (!priv->drivers_kset) {  
  48.         retval = -ENOMEM;  
  49.         goto bus_drivers_fail;  
  50.     }  
  51.   
  52.     INIT_LIST_HEAD(&priv->interfaces);  
  53.     __mutex_init(&priv->mutex, "subsys mutex", key);  
  54.     klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);  
  55.     klist_init(&priv->klist_drivers, NULL, NULL);  
  56.   
  57.     retval = add_probe_files(bus);  
  58.     if (retval)  
  59.         goto bus_probe_files_fail;  
  60.   
  61.     retval = bus_add_attrs(bus);  
  62.     if (retval)  
  63.         goto bus_attrs_fail;  
  64.   
  65.     pr_debug("bus: '%s': registered\n", bus->name);  
  66.     return 0;  
  67.   
  68. bus_attrs_fail:  
  69.     remove_probe_files(bus);  
  70. bus_probe_files_fail:  
  71.     kset_unregister(bus->p->drivers_kset);  
  72. bus_drivers_fail:  
  73.     kset_unregister(bus->p->devices_kset);  
  74. bus_devices_fail:  
  75.     bus_remove_file(bus, &bus_attr_uevent);  
  76. bus_uevent_fail:  
  77.     kset_unregister(&bus->p->subsys);  
  78. out:  
  79.     kfree(bus->p);  
  80.     bus->p = NULL;  
  81.     return retval;  
  82. }  


(2)设备结构体

[cpp]  view plain  copy
  1. struct device {  
  2.     struct device       *parent;               //指向父设备的指针  
  3.   
  4.     struct device_private   *p;  
  5.   
  6.     struct kobject kobj;                   //代表自身  
  7.     const char      *init_name; /* initial name of the device */  
  8.     const struct device_type *type;  
  9.   
  10.     struct mutex        mutex;  /* mutex to synchronize calls to 
  11.                      * its driver. 
  12.                      */  
  13.   
  14.     struct bus_type *bus;       /* type of bus device is on */         /* 所属的总线 */  
  15.     struct device_driver *driver;   /* which driver has allocated this /* 匹配的驱动*/  
  16.                        device */  
  17.     void        *platform_data; /* Platform specific data, device 
  18.                        core doesn't touch it */  
  19.     struct dev_pm_info  power;  
  20.     struct dev_pm_domain    *pm_domain;  
  21.   
  22. #ifdef CONFIG_NUMA  
  23.     int     numa_node;  /* NUMA node this device is close to */  
  24. #endif  
  25.     u64     *dma_mask;  /* dma mask (if dma'able device) */  
  26.     u64     coherent_dma_mask;/* Like dma_mask, but for 
  27.                          alloc_coherent mappings as 
  28.                          not all hardware supports 
  29.                          64 bit addresses for consistent 
  30.                          allocations such descriptors. */  
  31.   
  32.     struct device_dma_parameters *dma_parms;  
  33.   
  34.     struct list_head    dma_pools;  /* dma pools (if dma'ble) */  
  35.   
  36.     struct dma_coherent_mem *dma_mem; /* internal for coherent mem 
  37.                          override */  
  38.     /* arch specific additions */  
  39.     struct dev_archdata archdata;  
  40.   
  41.     struct device_node  *of_node; /* associated device tree node */  
  42.   
  43.     dev_t           devt;   /* dev_t, creates the sysfs "dev" */  设备号  
  44.     u32         id; /* device instance */  
  45.   
  46.     spinlock_t      devres_lock;  
  47.     struct list_head    devres_head;  
  48.   
  49.     struct klist_node   knode_class;  
  50.     struct class        *class;  
  51.     const struct attribute_group **groups;  /* optional groups */  
  52.   
  53.     void    (*release)(struct device *dev);//所有向内核注册的设备都必须有release()方法  
  54. };  
注册设备:

[cpp]  view plain  copy
  1. int device_register(struct device *dev)  
  2. {  
  3.     device_initialize(dev);  
  4.     return device_add(dev);  
  5. }  
  6. int device_add(struct device *dev)  
  7. {  
  8.     struct device *parent = NULL;  
  9.     struct kobject *kobj;  
  10.     struct class_interface *class_intf;  
  11.     int error = -EINVAL;  
  12.   
  13.     dev = get_device(dev);  
  14.     if (!dev)  
  15.         goto done;  
  16.   
  17.     if (!dev->p) {  
  18.         error = device_private_init(dev);  
  19.         if (error)  
  20.             goto done;  
  21.     }  
  22.   
  23.     /* 
  24.      * for statically allocated devices, which should all be converted 
  25.      * some day, we need to initialize the name. We prevent reading back 
  26.      * the name, and force the use of dev_name() 
  27.      */  
  28.     if (dev->init_name) {  
  29.         dev_set_name(dev, "%s", dev->init_name);  
  30.         dev->init_name = NULL;  
  31.     }  
  32.   
  33.     /* subsystems can specify simple device enumeration */  
  34.     if (!dev_name(dev) && dev->bus && dev->bus->dev_name)  
  35.         dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);  
  36.   
  37.     if (!dev_name(dev)) {  
  38.         error = -EINVAL;  
  39.         goto name_error;  
  40.     }  
  41.   
  42.     pr_debug("device: '%s': %s\n", dev_name(dev), __func__);  
  43.   
  44.     parent = get_device(dev->parent);  
  45.     kobj = get_device_parent(dev, parent);  
  46.     if (kobj)  
  47.         dev->kobj.parent = kobj;  
  48.   
  49.     /* use parent numa_node */  
  50.     if (parent)  
  51.         set_dev_node(dev, dev_to_node(parent));  
  52.   
  53.     /* first, register with generic layer. */  
  54.     /* we require the name to be set before, and pass NULL */  
  55.     error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);  
  56.     if (error)  
  57.         goto Error;  
  58.   
  59.     /* notify platform of device entry */  
  60.     if (platform_notify)  
  61.         platform_notify(dev);  
  62.   
  63.     error = device_create_file(dev, &uevent_attr);  
  64.     if (error)  
  65.         goto attrError;  
  66.   
  67.     if (MAJOR(dev->devt)) {  
  68.         error = device_create_file(dev, &devt_attr);  
  69.         if (error)  
  70.             goto ueventattrError;  
  71.   
  72.         error = device_create_sys_dev_entry(dev);  
  73.         if (error)  
  74.             goto devtattrError;  
  75.   
  76.         devtmpfs_create_node(dev);  
  77.     }  
  78.   
  79.     error = device_add_class_symlinks(dev);  
  80.     if (error)  
  81.         goto SymlinkError;  
  82.     error = device_add_attrs(dev);  
  83.     if (error)  
  84.         goto AttrsError;  
  85.     error = bus_add_device(dev);  
  86.     if (error)  
  87.         goto BusError;  
  88.     error = dpm_sysfs_add(dev);  
  89.     if (error)  
  90.         goto DPMError;  
  91.     device_pm_add(dev);  
  92.   
  93.     /* Notify clients of device addition.  This call must come 
  94.      * after dpm_sysfs_add() and before kobject_uevent(). 
  95.      */  
  96.     if (dev->bus)  
  97.         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,  
  98.                          BUS_NOTIFY_ADD_DEVICE, dev);  
  99.   
  100.     kobject_uevent(&dev->kobj, KOBJ_ADD);  
  101.     bus_probe_device(dev);  
  102.     if (parent)  
  103.         klist_add_tail(&dev->p->knode_parent,  
  104.                    &parent->p->klist_children);  
  105.   
  106.     if (dev->class) {  
  107.         mutex_lock(&dev->class->p->mutex);  
  108.         /* tie the class to the device */  
  109.         klist_add_tail(&dev->knode_class,  
  110.                    &dev->class->p->klist_devices);  
  111.   
  112.         /* notify any interfaces that the device is here */  
  113.         list_for_each_entry(class_intf,  
  114.                     &dev->class->p->interfaces, node)  
  115.             if (class_intf->add_dev)  
  116.                 class_intf->add_dev(dev, class_intf);  
  117.         mutex_unlock(&dev->class->p->mutex);  
  118.     }  
  119. done:  
  120.     put_device(dev);  
  121.     return error;  
  122.  DPMError:  
  123.     bus_remove_device(dev);  
  124.  BusError:  
  125.     device_remove_attrs(dev);  
  126.  AttrsError:  
  127.     device_remove_class_symlinks(dev);  
  128.  SymlinkError:  
  129.     if (MAJOR(dev->devt))  
  130.         devtmpfs_delete_node(dev);  
  131.     if (MAJOR(dev->devt))  
  132.         device_remove_sys_dev_entry(dev);  
  133.  devtattrError:  
  134.     if (MAJOR(dev->devt))  
  135.         device_remove_file(dev, &devt_attr);  
  136.  ueventattrError:  
  137.     device_remove_file(dev, &uevent_attr);  
  138.  attrError:  
  139.     kobject_uevent(&dev->kobj, KOBJ_REMOVE);  
  140.     kobject_del(&dev->kobj);  
  141.  Error:  
  142.     cleanup_device_parent(dev);  
  143.     if (parent)  
  144.         put_device(parent);  
  145. name_error:  
  146.     kfree(dev->p);  
  147.     dev->p = NULL;  
  148.     goto done;  
  149. }  

平台设备的注册,底层也是调用device_add()

[cpp]  view plain  copy
  1. int platform_device_register(struct platform_device *pdev)  
  2. {  
  3.     device_initialize(&pdev->dev);  
  4.     arch_setup_pdev_archdata(pdev);  
  5.     return platform_device_add(pdev);  
  6. }  

[cpp]  view plain  copy
  1. int platform_device_add(struct platform_device *pdev)  
  2. {  
  3.     int i, ret = 0;  
  4.   
  5.     if (!pdev)  
  6.         return -EINVAL;  
  7.   
  8.     if (!pdev->dev.parent)  
  9.         pdev->dev.parent = &platform_bus;  
  10.   
  11.     pdev->dev.bus = &platform_bus_type;  
  12.   
  13.     if (pdev->id != -1)  
  14.         dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);  
  15.     else  
  16.         dev_set_name(&pdev->dev, "%s", pdev->name);  
  17.   
  18.     for (i = 0; i < pdev->num_resources; i++) {  
  19.         struct resource *p, *r = &pdev->resource[i];  
  20.   
  21.         if (r->name == NULL)  
  22.             r->name = dev_name(&pdev->dev);  
  23.   
  24.         p = r->parent;  
  25.         if (!p) {  
  26.             if (resource_type(r) == IORESOURCE_MEM)  
  27.                 p = &iomem_resource;  
  28.             else if (resource_type(r) == IORESOURCE_IO)  
  29.                 p = &ioport_resource;  
  30.         }  
  31.   
  32.         if (p && insert_resource(p, r)) {  
  33.             printk(KERN_ERR  
  34.                    "%s: failed to claim resource %d\n",  
  35.                    dev_name(&pdev->dev), i);  
  36.             ret = -EBUSY;  
  37.             goto failed;  
  38.         }  
  39.     }  
  40.   
  41.     pr_debug("Registering platform device '%s'. Parent at %s\n",  
  42.          dev_name(&pdev->dev), dev_name(pdev->dev.parent));  
  43.   
  44.     ret = device_add(&pdev->dev);  
  45.     if (ret == 0)  
  46.         return ret;  
  47.   
  48.  failed:  
  49.     while (--i >= 0) {  
  50.         struct resource *r = &pdev->resource[i];  
  51.         unsigned long type = resource_type(r);  
  52.   
  53.         if (type == IORESOURCE_MEM || type == IORESOURCE_IO)  
  54.             release_resource(r);  
  55.     }  
  56.   
  57.     return ret;  
  58. }  

(3)驱动结构体

[cpp]  view plain  copy
  1. struct device_driver {  
  2.     const char      *name;    //设备驱动程序的名字  
  3.     struct bus_type     *bus; //设备驱动所属总线  
  4.   
  5.     struct module       *owner; //设备驱动自身模块  
  6.     const char      *mod_name;  /* 驱动模块的名字 */  
  7.   
  8.     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */  
  9.   
  10.     const struct of_device_id   *of_match_table;  
  11.   
  12.     int (*probe) (struct device *dev);  
  13.     int (*remove) (struct device *dev);  
  14.     void (*shutdown) (struct device *dev);  
  15.     int (*suspend) (struct device *dev, pm_message_t state);  
  16.     int (*resume) (struct device *dev);  
  17.     const struct attribute_group **groups;  
  18.   
  19.     const struct dev_pm_ops *pm;  
  20.   
  21.     struct driver_private *p;  
  22. };  
驱动注册

[cpp]  view plain  copy
  1. int driver_register(struct device_driver *drv)  
  2. {  
  3.     int ret;  
  4.     struct device_driver *other;  
  5.   
  6.     BUG_ON(!drv->bus->p);  
  7.   
  8.     if ((drv->bus->probe && drv->probe) ||  
  9.         (drv->bus->remove && drv->remove) ||  
  10.         (drv->bus->shutdown && drv->shutdown))  
  11.         printk(KERN_WARNING "Driver '%s' needs updating - please use "  
  12.             "bus_type methods\n", drv->name);  
  13.   
  14.     other = driver_find(drv->name, drv->bus);  
  15.     if (other) {  
  16.         printk(KERN_ERR "Error: Driver '%s' is already registered, "  
  17.             "aborting...\n", drv->name);  
  18.         return -EBUSY;  
  19.     }  
  20.   
  21.     ret = bus_add_driver(drv);  
  22.     if (ret)  
  23.         return ret;  
  24.     ret = driver_add_groups(drv, drv->groups);  
  25.     if (ret)  
  26.         bus_remove_driver(drv);  
  27.     return ret;  
  28. }  

又如平台驱动的注册,最终也是调用了driver_register

[cpp]  view plain  copy
  1. int platform_driver_register(struct platform_driver *drv)  
  2. {  
  3.     drv->driver.bus = &platform_bus_type;  
  4.     if (drv->probe)  
  5.         drv->driver.probe = platform_drv_probe;  
  6.     if (drv->remove)  
  7.         drv->driver.remove = platform_drv_remove;  
  8.     if (drv->shutdown)  
  9.         drv->driver.shutdown = platform_drv_shutdown;  
  10.   
  11.     return driver_register(&drv->driver);  
  12. }  



猜你喜欢

转载自blog.csdn.net/ds1130071727/article/details/80228101