关于sysfs的属性文件

来源:互联网 发布:单簧管和长笛 知乎 编辑:程序博客网 时间:2024/06/03 19:39

 关于sysfs的属性文件

预备知识

 在linux/include/linux/sysfs.h中:

/* FIXME
 * The *owner field is no longer used, but leave around
 * until the tree gets cleaned up fully.
 */
struct attribute {
    const char        * name;
    struct module        * owner;
    mode_t            mode;
};

struct attribute_group {
    const char        * name;
    struct attribute    ** attrs;
};


/**
 * Use these macros to make defining attributes easier. See include/linux/device.h
 * for examples..
 */

__ATTR是以后的几个属性文件定义的基本属性

#define __ATTR(_name,_mode,_show,_store) { \
    .attr = {.name = __stringify(_name), .mode = _mode },    \
    .show    = _show,                    \相对于读操作时调用的函数
    .store    = _store,                    \
}

#define __ATTR_RO(_name) { \
    .attr    = { .name = __stringify(_name), .mode = 0444 },    \
    .show    = _name##_show,                    \只有只读的文件操作函数
}

#define __ATTR_NULL { .attr = { .name = NULL } }

struct sysfs_ops {
    ssize_t    (*show)(struct kobject *, struct attribute *,char *);
    ssize_t    (*store)(struct kobject *,struct attribute *,const char *, size_t);
};


BUS_ATTR    DRIVER_ATTR   CLASS_ATTR    CLASS_DEVICE_ATTR    DEVICE_ATTR


DEVICE_ATTR是关于设备的属性文件宏定义

struct device_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct device *dev, struct device_attribute *attr,
            char *buf);
    ssize_t (*store)(struct device *dev, struct device_attribute *attr,
             const char *buf, size_t count);
};


#define DEVICE_ATTR(_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)

extern int __must_check    device_create_file(struct device *device,struct device_attribute * entry);
extern void   device_remove_file(struct device * dev, struct device_attribute * attr);


int device_create_file(struct device * dev, struct device_attribute * attr)
{
    int error = 0;
    if (get_device(dev)) {
        error = sysfs_create_file(&dev->kobj, &attr->attr);
        put_device(dev);
    }
    return error;
}

void device_remove_file(struct device * dev, struct device_attribute * attr)
{
    if (get_device(dev)) {
        sysfs_remove_file(&dev->kobj, &attr->attr);
        put_device(dev);
    }
}

BUS_ATTR 是关于总线的属性文件宏定义

linux/include/linux/device.h

struct bus_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct bus_type *, char * buf);
    ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};


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

extern int __must_check bus_create_file(struct bus_type *,
                    struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);



linux/drivers/base/bus.c

static struct sysfs_ops bus_sysfs_ops = {
    .show    = bus_attr_show,
    .store    = bus_attr_store,
};

int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{
    int error;
    if (get_bus(bus)) {
        error = sysfs_create_file(&bus->subsys.kobj, &attr->attr);
        put_bus(bus);
    } else
        error = -EINVAL;
    return error;
}

void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{
    if (get_bus(bus)) {
        sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
        put_bus(bus);
    }
}

static struct kobj_type bus_ktype = {
    .sysfs_ops    = &bus_sysfs_ops,
};


static int bus_uevent_filter(struct kset *kset, struct kobject *kobj)
{
    struct kobj_type *ktype = get_ktype(kobj);

    if (ktype == &bus_ktype)
        return 1;
    return 0;
}

static struct kset_uevent_ops bus_uevent_ops = {
    .filter = bus_uevent_filter,
};

static decl_subsys(bus, &bus_ktype, &bus_uevent_ops);




CLASS_ATTR是关于设备的属性文件宏定义

linux/include/linux/device.h

struct class_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct class *, char * buf);
    ssize_t (*store)(struct class *, const char * buf, size_t count);
};

#define CLASS_ATTR(_name,_mode,_show,_store)            \
struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)

extern int __must_check class_create_file(struct class *,
                    const struct class_attribute *);
extern void class_remove_file(struct class *, const struct class_attribute *);

linux/drivers/base/class.c


int class_create_file(struct class * cls, const struct class_attribute * attr)
{
    int error;
    if (cls) {
        error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
    } else
        error = -EINVAL;
    return error;
}

void class_remove_file(struct class * cls, const struct class_attribute * attr)
{
    if (cls)
        sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
}

CLASS_DEVICE_ATTR是关于类设备的属性文件宏定义
类也是一个设备
linux/include/linux/device.h

struct class_device_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct class_device *, char * buf);
    ssize_t (*store)(struct class_device *, const char * buf, size_t count);
};

#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store)        \
struct class_device_attribute class_device_attr_##_name =     \
    __ATTR(_name,_mode,_show,_store)


extern int __must_check class_device_create_file(struct class_device *,
                    const struct class_device_attribute *);

linux/drivers/base/class.c

int class_device_create_file(struct class_device * class_dev,
                 const struct class_device_attribute * attr)
{
    int error = -EINVAL;
    if (class_dev)
        error = sysfs_create_file(&class_dev->kobj, &attr->attr);
    return error;
}

DRIVER_ATTR 是关于驱动的属性文件宏定义

linux/include/linux/device.h

struct driver_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct device_driver *, char * buf);
    ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
};


#define DRIVER_ATTR(_name,_mode,_show,_store)    \
struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)


extern int __must_check driver_create_file(struct device_driver *,
                    struct driver_attribute *);
extern void driver_remove_file(struct device_driver *, struct driver_attribute *);

extern int __must_check driver_for_each_device(struct device_driver * drv,
        struct device *start, void *data,
        int (*fn)(struct device *, void *));
struct device * driver_find_device(struct device_driver *drv,
                   struct device *start, void *data,
                   int (*match)(struct device *, void *));

linux/drivers/base/driver.c
/**
 *    driver_create_file - create sysfs file for driver.
 *    @drv:    driver.
 *    @attr:    driver attribute descriptor.
 */

int driver_create_file(struct device_driver * drv, struct driver_attribute * attr)
{
    int error;
    if (get_driver(drv)) {
        error = sysfs_create_file(&drv->kobj, &attr->attr);
        put_driver(drv);
    } else
        error = -EINVAL;
    return error;
}

/**
 *    driver_remove_file - remove sysfs file for driver.
 *    @drv:    driver.
 *    @attr:    driver attribute descriptor.
 */

void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
{
    if (get_driver(drv)) {
        sysfs_remove_file(&drv->kobj, &attr->attr);
        put_driver(drv);
    }
}


0 0
原创粉丝点击