<form id="bpvnp"></form>

            <address id="bpvnp"><listing id="bpvnp"><meter id="bpvnp"></meter></listing></address>

                <address id="bpvnp"><nobr id="bpvnp"><menuitem id="bpvnp"></menuitem></nobr></address>

                    技术文摘

                    GSC3280的ADC子系统驱动模型(三)——class的使用












                    一个类是一个设备的高层视图,它抽象掉了底层的实现细节。例如,在驱动层面时,你可能会见到SCSI磁盘或者ATA磁盘;但在类层面时,它们都是磁盘。类允许用户空间基于它们做什么来使用设备,而不是它们如何被连接或者它们如何工作。

                    GSC3280的ADC子系统驱动模型(一)的3.1,程序adc_class = class_create(THIS_MODULE, "adc");产生一个class,class_create()函数如下:


                    1.  struct class {

                    2.      const char        *name;

                    3.      struct module        *owner;

                    4.   

                    5.      struct class_attribute        *class_attrs;

                    6.      struct device_attribute        *dev_attrs;

                    7.      struct bin_attribute        *dev_bin_attrs;

                    8.      struct kobject            *dev_kobj;

                    9.   

                    10.    int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);

                    11.    char *(*devnode)(struct device *dev, mode_t *mode);

                    12. 

                    13.    void (*class_release)(struct class *class);

                    14.    void (*dev_release)(struct device *dev);

                    15. 

                    16.    int (*suspend)(struct device *dev, pm_message_t state);

                    17.    int (*resume)(struct device *dev);

                    18. 

                    19.    const struct kobj_ns_type_operations *ns_type;

                    20.    const void *(*namespace)(struct device *dev);

                    21. 

                    22.    const struct dev_pm_ops *pm;

                    23. 

                    24.    struct subsys_private *p;

                    25.};

                    26.#define class_create(owner, name)        \

                    27.({                        \

                    28.    static struct lock_class_key __key;    \

                    29.    __class_create(owner, name, &__key);    \

                    30.})

                    31.struct class *__class_create(struct module *owner, const char *name,

                    32.             struct lock_class_key *key)

                    33.{

                    34.    struct class *cls;

                    35.    int retval;

                    36. 

                    37.    cls = kzalloc(sizeof(*cls), GFP_KERNEL);

                    38.    if (!cls) {

                    39.        retval = -ENOMEM;

                    40.        goto error;

                    41.    }

                    42. 

                    43.    cls->name = name;

                    44.    cls->owner = owner;

                    45.    cls->class_release = class_create_release;

                    46. 

                    47.    retval = __class_register(cls, key);

                    48.    if (retval)

                    49.        goto error;

                    50. 

                    51.    return cls;

                    52. 

                    53.error:

                    54.    kfree(cls);

                    55.    return ERR_PTR(retval);

                    56.}

                    57.int __class_register(struct class *cls, struct lock_class_key *key)

                    58.{

                    59.    struct subsys_private *cp;

                    60.    int error;

                    61. 

                    62.    pr_debug("device class '%s': registering\n", cls->name);

                    63. 

                    64.    cp = kzalloc(sizeof(*cp), GFP_KERNEL);

                    65.    if (!cp)

                    66.        return -ENOMEM;

                    67.    klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);

                    68.    INIT_LIST_HEAD(&cp->class_interfaces);

                    69.    kset_init(&cp->glue_dirs);

                    70.    __mutex_init(&cp->class_mutex, "struct class mutex", key);

                    71.    error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);

                    72.    if (error) {

                    73.        kfree(cp);

                    74.        return error;

                    75.    }

                    76. 

                    77.    /* set the default /sys/dev directory for devices of this class */

                    78.    if (!cls->dev_kobj)

                    79.        cls->dev_kobj = sysfs_dev_char_kobj;

                    80. 

                    81.#if defined(CONFIG_BLOCK)

                    82.    /* let the block class directory show up in the root of sysfs */

                    83.    if (!sysfs_deprecated || cls != &block_class)

                    84.        cp->subsys.kobj.kset = class_kset;

                    85.#else

                    86.    cp->subsys.kobj.kset = class_kset;

                    87.#endif

                    88.    cp->subsys.kobj.ktype = &class_ktype;

                    89.    cp->class = cls;

                    90.    cls->p = cp;

                    91. 

                    92.    error = kset_register(&cp->subsys);

                    93.    if (error) {

                    94.        kfree(cp);

                    95.        return error;

                    96.    }

                    97.    error = add_class_attrs(class_get(cls));

                    98.    class_put(cls);

                    99.    return error;

                    100.         }


                    说明:

                        1) class_create()函数是一个宏定义,具体调用了__class_create()函数。

                        2) __class_create()函数首先申请了一个class结构体内存,然后对其结构体成员变量赋值,最后调用__class_register()函数注册类。

                        3) __class_register()函数中,首先申请了结构体subsys_private内存,从class结构体成员可以看到,subsys_private是其一个成员指针。

                        4) 然后就是对subsys_private的成员变量初始化,注册subsys的kset,增加类属性等。

                     
                    GSC3280的ADC子系统驱动模型(二)的2.1中,介绍了sysfs的初始化,程序如下:

                    1.  void __init adc_sysfs_init(struct class *adc_class)

                    2.  {

                    3.      adc_class->dev_attrs = adc_attrs;

                    4.  }

                    说明:

                          1) 此处的类即是上面我们使用class_creat()创建的类。
                          2) 对类中的设备属性赋值,下面会讲述。


                    GSC3280的ADC子系统驱动模型(一)的3.2中,首先使用程序adc->dev.class = adc_class;将我们上面定义的类赋值给dev中的类,然后程序err = device_register(&adc->dev);注册这个设备,在这里的设备注册函数中,我们主要关注设备结构体中类的注册。device_register()函数如下:

                    1.  int device_register(struct device *dev)

                    2.  {

                    3.      device_initialize(dev);

                    4.      return device_add(dev);

                    5.  }

                    6.  void device_initialize(struct device *dev)

                    7.  {

                    8.      dev->kobj.kset = devices_kset;

                    9.      kobject_init(&dev->kobj, &device_ktype);

                    10.    INIT_LIST_HEAD(&dev->dma_pools);

                    11.    mutex_init(&dev->mutex);

                    12.    lockdep_set_novalidate_class(&dev->mutex);

                    13.    spin_lock_init(&dev->devres_lock);

                    14.    INIT_LIST_HEAD(&dev->devres_head);

                    15.    device_pm_init(dev);

                    16.    set_dev_node(dev, -1);

                    17.}

                    18.int device_add(struct device *dev)

                    19.{

                    20.    struct device *parent = NULL;

                    21.    struct class_interface *class_intf;

                    22.    int error = -EINVAL;

                    23. 

                    24.    dev = get_device(dev);

                    25.    if (!dev)

                    26.        goto done;

                    27. 

                    28.    if (!dev->p) {

                    29.        error = device_private_init(dev);

                    30.        if (error)

                    31.            goto done;

                    32.    }

                    33. 

                    34.    /*

                    35.     * for statically allocated devices, which should all be converted

                    36.     * some day, we need to initialize the name. We prevent reading back

                    37.     * the name, and force the use of dev_name()

                    38.     */

                    39.    if (dev->init_name) {

                    40.        dev_set_name(dev, "%s", dev->init_name);

                    41.        dev->init_name = NULL;

                    42.    }

                    43. 

                    44.    if (!dev_name(dev)) {

                    45.        error = -EINVAL;

                    46.        goto name_error;

                    47.    }

                    48. 

                    49.    pr_debug("device: '%s': %s\n", dev_name(dev), __func__);

                    50. 

                    51.    parent = get_device(dev->parent);

                    52.    setup_parent(dev, parent);

                    53. 

                    54.    /* use parent numa_node */

                    55.    if (parent)

                    56.        set_dev_node(dev, dev_to_node(parent));

                    57. 

                    58.    /* first, register with generic layer. */

                    59.    /* we require the name to be set before, and pass NULL */

                    60.    error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);

                    61.    if (error)

                    62.        goto Error;

                    63. 

                    64.    /* notify platform of device entry */

                    65.    if (platform_notify)

                    66.        platform_notify(dev);

                    67. 

                    68.    error = device_create_file(dev, &uevent_attr);

                    69.    if (error)

                    70.        goto attrError;

                    71. 

                    72.    if (MAJOR(dev->devt)) {

                    73.        error = device_create_file(dev, &devt_attr);

                    74.        if (error)

                    75.            goto ueventattrError;

                    76. 

                    77.        error = device_create_sys_dev_entry(dev);

                    78.        if (error)

                    79.            goto devtattrError;

                    80. 

                    81.        devtmpfs_create_node(dev);

                    82.    }

                    83. 

                    84.    error = device_add_class_symlinks(dev);

                    85.    if (error)

                    86.        goto SymlinkError;

                    87.    error = device_add_attrs(dev);

                    88.    if (error)

                    89.        goto AttrsError;

                    90.    error = bus_add_device(dev);

                    91.    if (error)

                    92.        goto BusError;

                    93.    error = dpm_sysfs_add(dev);

                    94.    if (error)

                    95.        goto DPMError;

                    96.    device_pm_add(dev);

                    97. 

                    98.    /* Notify clients of device addition. This call must come

                    99.     * after dpm_sysf_add() and before kobject_uevent().

                    100.              */

                    101.             if (dev->bus)

                    102.                 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,

                    103.                              BUS_NOTIFY_ADD_DEVICE, dev);

                    104.          

                    105.             kobject_uevent(&dev->kobj, KOBJ_ADD);

                    106.             bus_probe_device(dev);

                    107.             if (parent)

                    108.                 klist_add_tail(&dev->p->knode_parent,

                    109.                      &parent->p->klist_children);

                    110.          

                    111.             if (dev->class) {

                    112.                 mutex_lock(&dev->class->p->class_mutex);

                    113.                 /* tie the class to the device */

                    114.                 klist_add_tail(&dev->knode_class,

                    115.                      &dev->class->p->klist_devices);

                    116.          

                    117.                 /* notify any interfaces that the device is here */

                    118.                 list_for_each_entry(class_intf,

                    119.                          &dev->class->p->class_interfaces, node)

                    120.                     if (class_intf->add_dev)

                    121.                         class_intf->add_dev(dev, class_intf);

                    122.                 mutex_unlock(&dev->class->p->class_mutex);

                    123.             }

                    124.         done:

                    125.             put_device(dev);

                    126.             return error;

                    127.          DPMError:

                    128.             bus_remove_device(dev);

                    129.          BusError:

                    130.             device_remove_attrs(dev);

                    131.          AttrsError:

                    132.             device_remove_class_symlinks(dev);

                    133.          SymlinkError:

                    134.             if (MAJOR(dev->devt))

                    135.                 devtmpfs_delete_node(dev);

                    136.             if (MAJOR(dev->devt))

                    137.                 device_remove_sys_dev_entry(dev);

                    138.          devtattrError:

                    139.             if (MAJOR(dev->devt))

                    140.                 device_remove_file(dev, &devt_attr);

                    141.          ueventattrError:

                    142.             device_remove_file(dev, &uevent_attr);

                    143.          attrError:

                    144.             kobject_uevent(&dev->kobj, KOBJ_REMOVE);

                    145.             kobject_del(&dev->kobj);

                    146.          Error:

                    147.             cleanup_device_parent(dev);

                    148.             if (parent)

                    149.                 put_device(parent);

                    150.         name_error:

                    151.             kfree(dev->p);

                    152.             dev->p = NULL;

                    153.             goto done;

                    154.         }

                    说明:

                        1) device_register()函数首先调用device_initialize(dev);对dev成员初始化。

                        2) 然后调用device_add()函数增加设备。其中的device_add_attrs(dev)函数完成对类成员中的设备属性初始化,具体程序如下:

                    1.  static int device_add_attrs(struct device *dev)

                    2.  {

                    3.      struct class *class = dev->class;

                    4.      const struct device_type *type = dev->type;

                    5.      int error;

                    6.   

                    7.      if (class) {

                    8.          error = device_add_attributes(dev, class->dev_attrs);

                    9.          if (error)

                    10.            return error;

                    11.        error = device_add_bin_attributes(dev, class->dev_bin_attrs);

                    12.        if (error)

                    13.            goto err_remove_class_attrs;

                    14.    }

                    15. 

                    16.    if (type) {

                    17.        error = device_add_groups(dev, type->groups);

                    18.        if (error)

                    19.            goto err_remove_class_bin_attrs;

                    20.    }

                    21. 

                    22.    error = device_add_groups(dev, dev->groups);

                    23.    if (error)

                    24.        goto err_remove_type_groups;

                    25. 

                    26.    return 0;

                    27. 

                    28. err_remove_type_groups:

                    29.    if (type)

                    30.        device_remove_groups(dev, type->groups);

                    31. err_remove_class_bin_attrs:

                    32.    if (class)

                    33.        device_remove_bin_attributes(dev, class->dev_bin_attrs);

                    34. err_remove_class_attrs:

                    35.    if (class)

                    36.        device_remove_attributes(dev, class->dev_attrs);

                    37. 

                    38.    return error;

                    39.}

                    说明:

                        1) 由上面可知,dev成员中有class成员,但是class中只有对dev_attrs赋值了,dev成员中没有groups成员,所以此处执行的函数为device_add_attributes(dev, class->dev_attrs),程序如下:

                    1.  static int device_add_attributes(struct device *dev,

                    2.                   struct device_attribute *attrs)

                    3.  {

                    4.      int error = 0;

                    5.      int i;

                    6.   

                    7.      if (attrs) {

                    8.          for (i = 0; attr_name(attrs[i]); i++) {

                    9.              error = device_create_file(dev, &attrs[i]);

                    10.            if (error)

                    11.                break;

                    12.        }

                    13.        if (error)

                    14.            while (--i >= 0)

                    15.                device_remove_file(dev, &attrs[i]);

                    16.    }

                    17.    return error;

                    18.}

                    说明:

                         1) 最后是调用device_create_file(dev, &attrs[i]);产生文件的。此函数在其他文章中会介绍。







                    原文参见:http://blog.chinaunix.net/uid-25445243-id-4038871.html



















                     
                    彩神ll【中国】股份有限公司