6/26/2011 8:52:56 PM

来源:互联网 发布:淘宝微商的货一样吗 编辑:程序博客网 时间:2024/05/02 01:34

 

6/26/2011 8:52:56 PM

函数bus_add_attrs为本总线添加缺省属性文件,它将属性结构实例转换为sysfs中的属性文件,其列出如下:

static int bus_add_attrs(struct bus_type *bus)
{
 int error = 0;
 int i;
 
 if (bus->bus_attrs) {
  for (i = 0; attr_name(bus->bus_attrs[i]); i++) { /*遍历所有的总线属性实例*/
   error = bus_create_file(bus, &bus->bus_attrs[i]); /*创建属性文件*/
   if (error)
    goto err;
  }
 }
done:
 return error;
err:
 while (--i >= 0)
  bus_remove_file(bus, &bus->bus_attrs[i]);
 goto done;
}

添加缺省属性文件

一个设备类描述了一个设备类型,如音频设备和网卡设备,设备类结构device_class列出如下(在include/linux/devices.h中):

struct class {
 const char  *name;
 struct module  *owner;
 
 struct class_attribute  *class_attrs;   /*类属性*/
 struct device_attribute  *dev_attrs;
 struct kobject   *dev_kobj;
 
 int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
 
    /*下面域用于电源管理*/
 void (*class_release)(struct class *class);
 void (*dev_release)(struct device *dev);
 
 int (*suspend)(struct device *dev, pm_message_t state);
 int (*resume)(struct device *dev);
 
 struct pm_ops *pm;
 struct class_private *p;
};
结构class_private持有设备类对象结构class的私有数据,用于驱动程序核心代码,用户不应该使用。该结构描述了设备类内核对象间的关系。

结构class_private列出如下(在drivers/base/base.h中):

struct class_private {
 struct kset class_subsys;   /*设备类的内核对象集*/
 struct list_head class_devices;  /*与此设备类相关的设备链表*/
 struct list_head class_interfaces; /*与此设备类相关的类接口链表*/
 struct kset class_dirs;       /*与此设备类相关的虚拟设备的“胶合”目录*/
 struct mutex class_mutex;     /*保护设备类链表的互斥锁*/
 struct class *class;         /*回指结构class的指针*/
};
在sysfs文件系统中,所有设备类对象都在class目录下。该目录下的设备通过符号链接指向devices目录下的设备。目录class的部分内容列出如下:

^-^$ tree /sys/class
/sys/class
|-- backlight
|-- block
|   |-- dm-0 -> ../../devices/virtual/block/dm-0
|   |-- dm-1 -> ../../devices/virtual/block/dm-1
……
|-- mem
|   |-- full -> ../../devices/virtual/mem/full
|   |-- kmsg -> ../../devices/virtual/mem/kmsg
|   |-- mem -> ../../devices/virtual/mem/mem
|   |-- null -> ../../devices/virtual/mem/null
|   |-- oldmem -> ../../devices/virtual/mem/oldmem
|   |-- port -> ../../devices/virtual/mem/port
|   |-- random -> ../../devices/virtual/mem/random
|   |-- urandom -> ../../devices/virtual/mem/urandom
|   `-- zero -> ../../devices/virtual/mem/zero
……
|-- scsi_disk
|   |-- 0:0:0:0
|   |   |-- FUA
|   |   |-- allow_restart
|   |   |-- cache_type
|   |   |-- device -> ../../../devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0
|   |   |-- manage_start_stop
|   |   |-- subsystem -> ../../scsi_disk
|   |   `-- uevent
设备类用下列函数注册和注销:

extern int __must_check __class_register(struct class *class, struct lock_class_key *key);
extern void class_unregister(struct class *class);


设备类接口结构
设备类接口是直接与用户空间接口相关的设备类的逻辑接口,就象设备节点,用户可通过每个设备类的多个接口来访问同一个设备。如:一个SCSI硬盘将支持硬盘接口、SCSI通用接口和原始流设备接口。

设备注册到它们所属的类,当设备加到设备类中时,它们被加到与设备类注册到一起的每个接口中。这此接口负责决定设备是否支持某个接口。

设备类接口结构class_interface列出如下:

struct class_interface {
 struct list_head node;
 struct class  *class;
 
 int (*add_dev)  (struct device *, struct class_interface *);
 void (*remove_dev) (struct device *, struct class_interface *);
};
设备类接口的注册和注销函数列出如下:

extern int __must_check class_interface_register(struct class_interface *);
extern void class_interface_unregister(struct class_interface *);

类接口的注册和注销

一个接口必须定义它所属于的设备类,在注册时,该接口也被加到设备类的接口链表。接口在任何时候可被加到设备类中,当它被加入时,设备类中的每个设备被传递到接口的回调函数add_device。当一个接口被移除时,每个设备被从这个接口中移去。

当一个设备加到一个设备类时,它被加到设备类注册的每个接口中。

类接口

原创粉丝点击