LinuxKPI: Improve sysfs support.
- Add functions for creating and merging sysfs groups. - Add sysfs_streq function to compare strings ignoring newline from the sysctl userland call. - Add a call to sysfs_create_groups in device_add. - Remove duplicate header include. - Bump __FreeBSD_version. Reviewed by: hselasky Approved by: imp (mentor), hselasky MFC after: 4 days Differential Revision: D21542
This commit is contained in:
parent
2c24ffacd6
commit
f6668e9f56
@ -40,7 +40,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
@ -316,6 +315,10 @@ device_add(struct device *dev)
|
||||
dev->devt = makedev(0, device_get_unit(dev->bsddev));
|
||||
}
|
||||
kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
|
||||
|
||||
if (dev->groups)
|
||||
return (sysfs_create_groups(&dev->kobj, dev->groups));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -175,6 +175,27 @@ sysfs_remove_files(struct kobject *kobj, const struct attribute * const *attrs)
|
||||
sysfs_remove_file(kobj, attrs[i]);
|
||||
}
|
||||
|
||||
static inline int
|
||||
sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
{
|
||||
struct attribute **attr;
|
||||
struct sysctl_oid *oidp;
|
||||
|
||||
/* Don't create the group node if grp->name is undefined. */
|
||||
if (grp->name)
|
||||
oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(kobj->oidp),
|
||||
OID_AUTO, grp->name, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, grp->name);
|
||||
else
|
||||
oidp = kobj->oidp;
|
||||
for (attr = grp->attrs; *attr != NULL; attr++) {
|
||||
SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
|
||||
(*attr)->name, CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE,
|
||||
kobj, (uintptr_t)*attr, sysctl_handle_attr, "A", "");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
{
|
||||
@ -184,20 +205,40 @@ sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
}
|
||||
|
||||
static inline int
|
||||
sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
sysfs_create_groups(struct kobject *kobj, const struct attribute_group **grps)
|
||||
{
|
||||
int error = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; grps[i] && !error; i++)
|
||||
error = sysfs_create_group(kobj, grps[i]);
|
||||
while (error && --i >= 0)
|
||||
sysfs_remove_group(kobj, grps[i]);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static inline int
|
||||
sysfs_merge_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
{
|
||||
|
||||
/* Really expected behavior is to return failure if group exists. */
|
||||
return (sysfs_create_group(kobj, grp));
|
||||
}
|
||||
|
||||
static inline void
|
||||
sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
{
|
||||
struct attribute **attr;
|
||||
struct sysctl_oid *oidp;
|
||||
|
||||
oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(kobj->oidp),
|
||||
OID_AUTO, grp->name, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, grp->name);
|
||||
for (attr = grp->attrs; *attr != NULL; attr++) {
|
||||
SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
|
||||
(*attr)->name, CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE,
|
||||
kobj, (uintptr_t)*attr, sysctl_handle_attr, "A", "");
|
||||
SLIST_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp), oid_link) {
|
||||
if (strcmp(oidp->oid_name, grp->name) != 0)
|
||||
continue;
|
||||
for (attr = grp->attrs; *attr != NULL; attr++) {
|
||||
sysctl_remove_name(oidp, (*attr)->name, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -224,6 +265,22 @@ sysfs_remove_dir(struct kobject *kobj)
|
||||
sysctl_remove_oid(kobj->oidp, 1, 1);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
sysfs_streq(const char *s1, const char *s2)
|
||||
{
|
||||
int l1, l2;
|
||||
|
||||
l1 = strlen(s1);
|
||||
l2 = strlen(s2);
|
||||
|
||||
if (l1 != 0 && s1[l1-1] == '\n')
|
||||
l1--;
|
||||
if (l2 != 0 && s2[l2-1] == '\n')
|
||||
l2--;
|
||||
|
||||
return (l1 == l2 && strncmp(s1, s2, l1) == 0);
|
||||
}
|
||||
|
||||
#define sysfs_attr_init(attr) do {} while(0)
|
||||
|
||||
#endif /* _LINUX_SYSFS_H_ */
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1300045 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1300046 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
Loading…
Reference in New Issue
Block a user