Commit 2ce5e0bc authored by Patrick Mochel's avatar Patrick Mochel

Allow subsystem to have attributes, too.

This is really handy for subsystems that have any attributes they want
to export, esp. if they have just a few, since they don't have to define
all of the infrastructure for creating and tearing down the attributes 
for the high level type that they are. 

- define struct subsys_attribute for declaring attributes of subsystems
themselves. 

- define subsys_create_file() and subsys_remove_file().

- define subsys_sysfs_ops for forwarding sysfs reads and writes to the 
subsystem attribute callbacks. 

- Set the sysfs_ops to be the subsystem ones if the kobject doesn't belong
to a subsystem itself (meaning that it is a subsystem).
parent 35551cf5
......@@ -145,6 +145,43 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char *
return error;
}
#define to_subsys(k) container_of(k,struct subsystem,kobj)
#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
/**
* Subsystem file operations.
* These operations allow subsystems to have files that can be
* read/written.
*/
ssize_t subsys_attr_show(struct kobject * kobj, struct attribute * attr,
char * page, size_t count, loff_t off)
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
ssize_t ret = 0;
if (sattr->show)
ret = sattr->show(s,page,count,off);
return ret;
}
ssize_t subsys_attr_store(struct kobject * kobj, struct attribute * attr,
const char * page, size_t count, loff_t off)
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
ssize_t ret = 0;
if (sattr->store)
ret = sattr->store(s,page,count,off);
return ret;
}
static struct sysfs_ops subsys_sysfs_ops = {
.show = subsys_attr_show,
.store = subsys_attr_store,
};
/**
* sysfs_read_file - read an attribute.
* @file: file pointer.
......@@ -265,9 +302,14 @@ static int check_perm(struct inode * inode, struct file * file)
if (!kobj || !attr)
goto Einval;
/* if the kobject has no subsystem, then it is a subsystem itself,
* so give it the subsys_sysfs_ops.
*/
if (kobj->subsys)
ops = kobj->subsys->sysfs_ops;
else
ops = &subsys_sysfs_ops;
/* No sysfs operations, either from having no subsystem,
* or the subsystem have no operations.
......
......@@ -60,4 +60,13 @@ static inline void subsys_put(struct subsystem * s)
kobject_put(&s->kobj);
}
struct subsys_attribute {
struct attribute attr;
ssize_t (*show)(struct subsystem *, char *, size_t, loff_t);
ssize_t (*store)(struct subsystem *, const char *, size_t, loff_t);
};
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
#endif /* _KOBJECT_H_ */
......@@ -229,6 +229,38 @@ void subsystem_unregister(struct subsystem * s)
}
/**
* subsystem_create_file - export sysfs attribute file.
* @s: subsystem.
* @a: subsystem attribute descriptor.
*/
int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
{
int error = 0;
if (subsys_get(s)) {
error = sysfs_create_file(&s->kobj,&a->attr);
subsys_put(s);
}
return error;
}
/**
* subsystem_remove_file - remove sysfs attribute file.
* @s: subsystem.
* @a: attribute desciptor.
*/
void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
{
if (subsys_get(s)) {
sysfs_remove_file(&s->kobj,&a->attr);
subsys_put(s);
}
}
EXPORT_SYMBOL(kobject_init);
EXPORT_SYMBOL(kobject_register);
EXPORT_SYMBOL(kobject_unregister);
......@@ -238,3 +270,5 @@ EXPORT_SYMBOL(kobject_put);
EXPORT_SYMBOL(subsystem_init);
EXPORT_SYMBOL(subsystem_register);
EXPORT_SYMBOL(subsystem_unregister);
EXPORT_SYMBOL(subsys_create_file);
EXPORT_SYMBOL(subsys_remove_file);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment