设备驱动中bus代表实际的总线,device代表实际的设备和接口,而device_driver则对应存在的驱动。而class,是设备类,完全是抽象出来的概念,没有对应的实体。所谓设备类,是指提供的用户接口相似的一类设备的集合,常见的设备类的有block、tty、input、usb等等。
struct class
就是设备驱动模型中通用的设备类结构。
class对应的代码在drivers/base/class.c中,对应的头文件在include/Linux/device.h和drivers/base/base.h中。还是先来看class涉及的结构:
/**
* struct class - device classes
* @name: Name of the class.
* @owner: The module owner.
* @class_attrs: Default attributes of this class.
* @dev_groups: Default attributes of the devices that belong to the class.
* @dev_kobj: The kobject that represents this class and links it into the hierarchy.
* @dev_uevent: Called when a device is added, removed from this class, or a
* few other things that generate uevents to add the environment
* variables.
* @devnode: Callback to provide the devtmpfs.
* @class_release: Called to release this class.
* @dev_release: Called to release the device.
* @suspend: Used to put the device to sleep mode, usually to a low power
* state.
* @resume: Used to bring the device from the sleep mode.
* @ns_type: Callbacks so sysfs can detemine namespaces.
* @namespace: Namespace of the device belongs to this class.
* @pm: The default device power management operations of this class.
* @p: The private data of the driver core, no one other than the
* driver core can touch this.
*
* A class is a higher-level view of a device that abstracts out low-level
* implementation details. Drivers may see a SCSI disk or an ATA disk, but,
* at the class level, they are all simply disks. Classes allow user space
* to work with devices based on what they do, rather than how they are
* connected or how they work.
*/
struct class {
const char *name;//代表类名称,和bus/device/driver中的名称一样,是初始名称,实际使用的是内部kobj包含的动态创建的名称。
struct module *owner;//class所属的模块,虽然class是涉及一类设备,但也是由相应的模块注册的
struct class_attribute *class_attrs;//class给自己添加的属性,dev_groups是class给所包含的设备添加的属性
const struct attribute_group **dev_groups;
struct kobject *dev_kobj; //一个kobject指针
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); //在设备发出uevent消息时添加环境变量用的
char *(*devnode)(struct device *dev, umode_t *mode); //返回设备节点的相对路径名
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);//恢复设备时调用
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
const struct dev_pm_ops *pm;//电源管理用的函数集合
struct subsys_private *p; //指向subsys_private结构的指针
};
p是指向struct subsys_private
的指针,老的内核版本中是class_private
表示,即class的私有数据:
/**
* struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
*
* @subsys - the struct kset that defines this subsystem
* @devices_kset - the subsystem's 'devices' directory
* @interfaces - list of subsystem interfaces associated
* @mutex - protect the devices, and interfaces lists.
*
* @drivers_kset - the list of drivers associated
* @klist_devices - the klist to iterate over the @devices_kset
* @klist_drivers - the klist to iterate over the @drivers_kset
* @bus_notifier - the bus notifier list for anything that cares about things
* on this bus.
* @bus - pointer back to the struct bus_type that this structure is associated
* with.
*
* @glue_dirs - "glue" directory to put in-between the parent device to
* avoid namespace conflicts
* @class - pointer back to the struct class that this structure is associated
* with.
*
* This structure is the one that is the actual kobject allowing struct
* bus_type/class to be statically allocated safely. Nothing outside of the
* driver core should ever touch these fields.
*/
struct subsys_private {
struct kset subsys;//kset类型,用来表示class在sysfs中的位置
struct kset *devices_kset; //指向device的kset指针
struct list_head interfaces; //是list_head类型的类接口链表
struct mutex mutex;
struct kset *drivers_kset;
struct klist klist_devices; //klist设备链
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1;
struct bus_type *bus;
struct kset glue_dirs;
struct class *class;
};
#define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj)
<