微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 手机设计讨论 > MTK手机平台交流 > Linux设备模型分析之bus --转

Linux设备模型分析之bus --转

时间:10-02 整理:3721RD 点击:
Linux设备模型分析之bus
内核版本:2.6.36
前面我们分析了linux设备模型中kobject、kset以及ktype的使用,它们是设备模型的最基础部分,在其上有更高级一层的bus、device和driver。在这一篇文章中,我们来看一下bus的用法。 一、相关数据结构首先,我们列出本文涉及的相关数据结构。[cpp] view plaincopyprint?

    51struct bus_type {  
  • 52    const char      *name;  
    53    struct bus_attribute    *bus_attrs;  
  • 54    struct device_attribute *dev_attrs;  
    55    struct driver_attribute *drv_attrs;  
  • 56  
    57    int (*match)(struct device *dev, struct device_driver *drv);  
  • 58    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  
    59    int (*probe)(struct device *dev);  
  • 60    int (*remove)(struct device *dev);  
    61    void (*shutdown)(struct device *dev);  
  • 62  
    63    int (*suspend)(struct device *dev, pm_message_t state);  
  • 64    int (*resume)(struct device *dev);  
    65  
  • 66    const struct dev_pm_ops *pm;  
    67  
  • 68    struct bus_type_private *p;  
    69};  
  •    
    38struct bus_attribute {  
  • 39    struct attribute    attr;  
    40    ssize_t (*show)(struct bus_type *bus, char *buf);  
  • 41    ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);  
    42};  
  •    
    336/* interface for exporting device attributes */  
  • 337struct device_attribute {  
    338    struct attribute    attr;  
  • 339    ssize_t (*show)(struct device *dev, struct device_attribute *attr,  
    340            char *buf);  
  • 341    ssize_t (*store)(struct device *dev, struct device_attribute *attr,  
    342             const char *buf, size_t count);  
  • 343};  
       
  • 162struct driver_attribute {  
    163    struct attribute attr;  
  • 164    ssize_t (*show)(struct device_driver *driver, char *buf);  
    165    ssize_t (*store)(struct device_driver *driver, const char *buf,  
  • 166             size_t count);  
    167};  
  •    
      2/**
  •   3 * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.
      4 *
  •   5 * @subsys - the struct kset that defines this bus.  This is the main kobject
      6 * @drivers_kset - the list of drivers associated with this bus
  •   7 * @devices_kset - the list of devices associated with this bus
      8 * @klist_devices - the klist to iterate over the @devices_kset
  •   9 * @klist_drivers - the klist to iterate over the @drivers_kset
    10 * @bus_notifier - the bus notifier list for anything that cares about things
  • 11 * on this bus.
    12 * @bus - pointer back to the struct bus_type that this structure is associated
  • 13 * with.
    14 *
  • 15 * This structure is the one that is the actual kobject allowing struct
    16 * bus_type to be statically allocated safely.  Nothing outside of the driver
  • 17 * core should ever touch these fields.
    18 */  
  • 19struct bus_type_private {  
    20    struct kset subsys;  
  • 21    struct kset *drivers_kset;  
    22    struct kset *devices_kset;  
  • 23    struct klist klist_devices;  
    24    struct klist klist_drivers;  
  • 25    struct blocking_notifier_head bus_notifier;  
    26    unsigned int drivers_autoprobe:1;  
  • 27    struct bus_type *bus;  
    28};  
  •    
    406struct device {  
  • 407    struct device       *parent;  
    408  
  • 409    struct device_private   *p;  
    410  
  • 411    struct kobject kobj;  
    412    const char      *init_name; /* initial name of the device */  
  • 413    struct device_type  *type;  
    414  
  • 415    struct mutex        mutex;  /* mutex to synchronize calls to
    416                     * its driver.
  • 417                     */  
    418  
  • 419    struct bus_type *bus;       /* type of bus device is on */  
    420    struct device_driver *driver;   /* which driver has allocated this
  • 421                       device */  
    422    void        *platform_data; /* Platform specific data, device
  • 423                       core doesn't touch it */  
    424    struct dev_pm_info  power;  
  • 425  
    426#ifdef CONFIG_NUMA  
  • 427    int     numa_node;  /* NUMA node this device is close to */  
    428#endif  
  • 429    u64     *DMA_mask;  /* dma mask (if dma'able device) */  
    430    u64     coherent_dma_mask;/* Like dma_mask, but for
  • 431                         alloc_coherent mappings as
    432                         not all hardware supports
  • 433                         64 bit addresses for consistent
    434                         allocations such descriptors. */  
  • 435  
    436    struct device_dma_parameters *dma_pARMs;  
  • 437  
    438    struct list_head    dma_pools;  /* dma pools (if dma'ble) */  
  • 439  
    440    struct dma_coherent_mem *dma_mem; /* internal for coherent mem
  • 441                         override */  
    442    /* arch specific additions */  
  • 443    struct dev_archdata archdata;  
    444#ifdef CONFIG_OF  
  • 445    struct device_node  *of_node;  
    446#endif  
  • 447  
    448    dev_t           devt;   /* dev_t, creates the sysfs "dev" */  
  • 449  
    450    SPInlock_t      devres_lock;  
  • 451    struct list_head    devres_head;  
    452  
  • 453    struct klist_node   knode_class;  
    454    struct class        *class;  
  • 455    const struct attribute_group **groups;  /* optional groups */  
    456  
  • 457    void    (*release)(struct device *dev);  
    458};  
  •    
    123struct device_driver {  
  • 124    const char      *name;  
    125    struct bus_type     *bus;  
  • 126  
    127    struct module       *owner;  
  • 128    const char      *mod_name;  /* used for built-in modules */  
    129  
  • 130    bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */  
    131  
  • 132#if defined(CONFIG_OF)  
    133    const struct of_device_id   *of_match_table;  
  • 134#endif  
    135  
  • 136    int (*probe) (struct device *dev);  
    137    int (*remove) (struct device *dev);  
  • 138    void (*shutdown) (struct device *dev);  
    139    int (*suspend) (struct device *dev, pm_message_t state);  
  • 140    int (*resume) (struct device *dev);  
    141    const struct attribute_group **groups;  
  • 142  
    143    const struct dev_pm_ops *pm;  
  • 144  
    145    struct driver_private *p;  
  • 146};  

二、注册busbus的注册接口为bus_register,该函数代码如下:[cpp] view plaincopyprint?

    872/**
  • 873 * bus_register - register a bus with the system.
    874 * @bus: bus.
  • 875 *
    876 * Once we have that, we registered the bus with the kobject
  • 877 * infrastructure, then register the children subsystEMS it has:
    878 * the devices and drivers that belong to the bus.
  • 879 */  
    880int bus_register(struct bus_type *bus)  
  • 881{  
    882    int retval;  
  • 883    struct bus_type_private *priv;  
    884  
  • 885    priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);  
    886    if (!priv)  
  • 887        return -ENOMEM;  
    888  
  • 889    priv->bus = bus;  
    890    bus->p = priv;  
  • 891  
    892    BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);  
  • 893  
    894    retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);  
  • 895    if (retval)  
    896        goto out;  
  • 897  
    898    priv->subsys.kobj.kset = bus_kset;  
  • 899    priv->subsys.kobj.ktype = &bus_ktype;  
    900    priv->drivers_autoprobe = 1;  
  • 901  
    902    retval = kset_register(&priv->subsys);  
  • 903    if (retval)  
    904        goto out;  
  • 905  
    906    retval = bus_create_file(bus, &bus_attr_uevent);  
  • 907    if (retval)  
    908        goto bus_uevent_fail;  
  • 909  
    910    priv->devices_kset = kset_create_and_add("devices", NULL,  
  • 911                         &priv->subsys.kobj);  
    912    if (!priv->devices_kset) {  
  • 913        retval = -ENOMEM;  
    914        goto bus_devices_fail;  
  • 915    }  
    916  
  • 917    priv->drivers_kset = kset_create_and_add("drivers", NULL,  
    918                         &priv->subsys.kobj);  
  • 919    if (!priv->drivers_kset) {  
    920        retval = -ENOMEM;  
  • 921        goto bus_drivers_fail;  
    922    }  
  • 923  
    924    klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);  
  • 925    klist_init(&priv->klist_drivers, NULL, NULL);  
    926  
  • 927    retval = add_probe_files(bus);  
    928    if (retval)  
  • 929        goto bus_probe_files_fail;  
    930  
  • 931    retval = bus_add_attrs(bus);  
    932    if (retval)  
  • 933        goto bus_attrs_fail;  
    934  
  • 935    pr_debug("bus: '%s': registered\n", bus->name);  
    936    return 0;  
  • 937  
    938bus_attrs_fail:  
  • 939    remove_probe_files(bus);  
    940bus_probe_files_fail:  
  • 941    kset_unregister(bus->p->drivers_kset);  
    942bus_drivers_fail:  
  • 943    kset_unregister(bus->p->devices_kset);  
    944bus_devices_fail:  
  • 945    bus_remove_file(bus, &bus_attr_uevent);  
    946bus_uevent_fail:  
  • 947    kset_unregister(&bus->p->subsys);  
    948out:  
  • 949    kfree(bus->p);  
    950    bus->p = NULL;  
  • 951    return retval;  
  • 952}  

894行,设置priv->subsys.kobj的名字,priv->subsys是一个kset,代表这个bus。bus是通过一个kset来表示的,而device和device_driver都是通过一个kobject来表示的,由此也可以看出他们的不同。898行,设置priv->subsys.kobj.kset为bus_kset;在drivers/base/bus.c文件中,162行有如下定义:[cpp] view plaincopyprint?

  • 162static struct kset *bus_kset;  

162static struct kset *bus_kset;
同时,在buses_init函数中对bus_kset进行了初始化:[cpp] view plaincopyprint?

    1054int __init buses_init(void)  
  • 1055{  
    1056    bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);  
  • 1057    if (!bus_kset)  
    1058        return -ENOMEM;  
  • 1059    return 0;  
  • 1060}  

1056行,创建一个名为bus的kset,赋值给bus_kset,对应/sys/bus目录。所有的bus都属性bus_set,即所有的bus对应的sys系统目录都放在/sys/bus目录下。bus_kset对应的kset_uevent_ops是bus_uevent_ops,其定义如下:[cpp] view plaincopyprint?

    158static const struct kset_uevent_ops bus_uevent_ops = {  
  • 159    .fiLTEr = bus_uevent_filter,  
  • 160};  

158static const struct kset_uevent_ops bus_uevent_ops = {159    .filter = bus_uevent_filter,160};
bus_uevent_filter函数定义如下:[cpp] view plaincopyprint?

    149static int bus_uevent_filter(struct kset *kset, struct kobject *kobj)  
  • 150{  
    151    struct kobj_type *ktype = get_ktype(kobj);  
  • 152  
    153    if (ktype == &bus_ktype)  
  • 154        return 1;  
    155    return 0;  
  • 156}  

回忆一下上一篇博客《Linux设备模型分析之kset》介绍的内容,如果kset_uevent_ops.filter函数返回0,将不会处理uevent事件。在bus_uevent_filter函数中,如果kobj->ktype不是bus_ktype,则返回0,即不处理Uevent事件。bus_ktype定义如下:[cpp] view plaincopyprint?

    145static struct kobj_type bus_ktype = {  
  • 146    .sysfs_ops  = &bus_sysfs_ops,  
  • 147};  

145static struct kobj_type bus_ktype = {146    .sysfs_ops  = &bus_sysfs_ops,147};
bus_sysfs_ops定义如下:[cpp] view plaincopyprint?

    119static const struct sysfs_ops bus_sysfs_ops = {  
  • 120    .show   = bus_attr_show,  
    121    .store  = bus_attr_store,  
  • 122};  

119static const struct sysfs_ops bus_sysfs_ops = {120    .show   = bus_attr_show,121    .store  = bus_attr_store,122};
bus_attr_show和bus_attr_store函数定义如下:[cpp] view plaincopyprint?

    95static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,  
  • 96                 char *buf)  
    97{  
  • 98    struct bus_attribute *bus_attr = to_bus_attr(attr);  
    99    struct bus_type_private *bus_priv = to_bus(kobj);  
  • 100    ssize_t ret = 0;  
    101  
  • 102    if (bus_attr->show)  
    103        ret = bus_attr->show(bus_priv->bus, buf);  
  • 104    return ret;  
    105}  
  • 106  
    107static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,  
  • 108                  const char *buf, size_t count)  
    109{  
  • 110    struct bus_attribute *bus_attr = to_bus_attr(attr);  
    111    struct bus_type_private *bus_priv = to_bus(kobj);  
  • 112    ssize_t ret = 0;  
    113  
  • 114    if (bus_attr->store)  
    115        ret = bus_attr->store(bus_priv->bus, buf, count);  
  • 116    return ret;  
  • 117}  

bus_attribute结构体定义如下:[cpp] view plaincopyprint?

    38struct bus_attribute {  
  • 39    struct attribute    attr;  
    40    ssize_t (*show)(struct bus_type *bus, char *buf);  
  • 41    ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);  
  • 42};  

回到bus_register函数:899行,设置priv->subsys.kobj.ktype为 &bus_ktype;回忆一下前面的文章《Linux设备模型分析之kobject》,对kobject属性的读写操作将调用kobject.ktype定义的sysfs_ops函数集指定的show和store函数。所以对bus属性文件的读写操作将会调用bus_ktyp.sysfs_ops指定的bus_attr_show和bus_attr_store函数,这两个函数我们前面已经分析过了,他们将回溯到bus_attr->show和bus_attr->store函数。900行,设置priv->drivers_autoprobe为1;902行,调用kset_register注册priv->subsys,即注册代表bus的kset。注册完成后,将在/sys/bus目录下出现对应该bus的目录。906行,调用bus_create_file(bus, &bus_attr_uevent),创建uevent属性文件,该函数定义如下:[cpp] view plaincopyprint?

    124int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)  
  • 125{  
    126    int error;  
  • 127    if (bus_get(bus)) {  
    128        error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr);  
  • 129        bus_put(bus);  
    130    } else  
  • 131        error = -EINVAL;  
    132    return error;  
  • 133}  

128行,调用sysfs_create_file函数创建了bus_attribute对应的属性文件。先来看bus_attr_uevent的定义,它是通过宏BUS_ATTR生成的:[cpp] view plaincopyprint?

  • 870static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);  

870static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
BUS_ATTR定义如下:[cpp] view plaincopyprint?

    44#define BUS_ATTR(_name, _mode, _show, _store)   \  
  • 45struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)  

44#define BUS_ATTR(_name, _mode, _show, _store)   \45struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
__ATTR定义如下:[cpp] view plaincopyprint?

    70#define __ATTR(_name,_mode,_show,_store) { \  
  • 71    .attr = {.name = __stringify(_name), .mode = _mode },   \  
    72    .show   = _show,                    \  
  • 73    .store  = _store,                   \  
  • 74}  

70#define __ATTR(_name,_mode,_show,_store) { \71    .attr = {.name = __stringify(_name), .mode = _mode },   \72    .show   = _show,                    \73    .store  = _store,                   \74}
从bus_attr_uevent的定义可以看出,对应的uevent属性只有store接口,没有实现show接口。store接口函数bus_uevent_store定义如下:[cpp] view plaincopyprint?

    861static ssize_t bus_uevent_store(struct bus_type *bus,  
  • 862                const char *buf, size_t count)  
    863{  
  • 864    enum kobject_action action;  
    865  
  • 866    if (kobject_action_type(buf, count, &action) == 0)  
    867        kobject_uevent(&bus->p->subsys.kobj, action);  
  • 868    return count;  
  • 869}  

回到bus_register函数:910 - 915行,创建名为devices的kset,其parent是priv->subsys.kobj,即在相应bus目录下创建一个devices目录。917 - 922行,创建名为drivers的kset,其parent是priv->subsys.kobj,即在相应bus目录下创建一个drivers目录。924行,初始化priv->klist_devices,即devices链表。925行,初始化priv->klist_drivers,即drivers链表。927行,调用add_probe_files(bus)函数创建drivers_probe和drivers_autoprobe两个属性文件,该函数定义如下:[cpp] view plaincopyprint?

    606static int add_probe_files(struct bus_type *bus)  
  • 607{  
    608    int retval;  
  • 609  
    610    retval = bus_create_file(bus, &bus_attr_drivers_probe);  
  • 611    if (retval)  
    612        goto out;  
  • 613  
    614    retval = bus_create_file(bus, &bus_attr_drivers_autoprobe);  
  • 615    if (retval)  
    616        bus_remove_file(bus, &bus_attr_drivers_probe);  
  • 617out:  
    618    return retval;  
  • 619}  

bus_create_file函数我们前面已经分析过了,610行,创建drivers_probe属性文件,614行,创建drivers_autoprobe属性文件。其对应的bus_attribute定义如下:[cpp] view plaincopyprint?

    602static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe);  
  • 603static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO,  
  • 604        show_drivers_autoprobe, store_drivers_autoprobe);  

602static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe);603static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO,604        show_drivers_autoprobe, store_drivers_autoprobe);
属性文件对应的操作函数定义如下:[cpp] view plaincopyprint?

    225static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)  
  • 226{  
    227    return sprintf(buf, "%d\n", bus->p->drivers_autoprobe);  
  • 228}  
    229  
  • 230static ssize_t store_drivers_autoprobe(struct bus_type *bus,  
    231                       const char *buf, size_t count)  
  • 232{  
    233    if (buf[0] == '0')  
  • 234        bus->p->drivers_autoprobe = 0;  
    235    else  
  • 236        bus->p->drivers_autoprobe = 1;  
    237    return count;  
  • 238}  
    239  
  • 240static ssize_t store_drivers_probe(struct bus_type *bus,  
    241                   const char *buf, size_t count)  
  • 242{  
    243    struct device *dev;  
  • 244  
    245    dev = bus_find_device_by_name(bus, NULL, buf);  
  • 246    if (!dev)  
    247        return -ENODEV;  
  • 248    if (bus_rescan_devices_helper(dev, NULL) != 0)  
    249        return -EINVAL;  
  • 250    return count;  
  • 251}  

show_drivers_autoprobe函数用于显示bus->p->drivers_autoprobe的值。store_drivers_autoprobe函数根据用户的要求设置bus->p->drivers_autoprobe的值。store_drivers_probe函数245行调用bus_find_device_by_name 在bus上查找用户指定的device,并且在248行调用bus_rescan_devices_helper函数查找匹配device_driver.回到bus_register函数:931行,调用bus_add_attrs函数创建bus默认属性文件,该函数定义如下:[cpp] view plaincopyprint?

    810/**
  • 811 * bus_add_attrs - Add default attributes for this bus.
    812 * @bus: Bus that has just been registered.
  • 813 */  
    814  
  • 815static int bus_add_attrs(struct bus_type *bus)  
    816{  
  • 817    int error = 0;  
    818    int i;  
  • 819  
    820    if (bus->bus_attrs) {  
  • 821        for (i = 0; attr_name(bus->bus_attrs); i++) {  
    822            error = bus_create_file(bus, &bus->bus_attrs);  
  • 823            if (error)  
    824                goto err;  
  • 825        }  
    826    }  
  • 827done:  
    828    return error;  
  • 829err:  
    830    while (--i >= 0)  
  • 831        bus_remove_file(bus, &bus->bus_attrs);  
    832    goto done;  
  • 833}  

820 - 826行,如果bus->bus_attrs指定了bus的默认属性,则创建对应的属性文件。

请问一下,你是怎么COPY的。可以这样显示。
我怎么每次COPY过来都是显示是普通的。并不能显示代码编写的样子。

选中,右键,复制粘贴。
这个可能跟源网页的格式有关。
你不说我都没仔细看,我当时发表的时候不是这个样子的,当时就像txt中的那样,发表完了我还看了一遍,这什么时候变成这个样子了。
中间还有乱七八糟的部分,好像是前面代码段的重复。关键是汉字描述部分,看着太难受了。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top