linuxkpi: Handle bin attributes in sysfs attribute groups
For instance, this is used by DRM drivers to declare the EDID property
of an GPU output connector:
sysctl -b sys.device.drmn1.card0.card0-DP-1.edid | edid-decode
...
Block 0, Base EDID:
EDID Structure Version & Revision: 1.4
Vendor & Product Identification:
Manufacturer: SAM
Model: 29814
Serial Number: 810635354 (0x3051505a)
Made in: week 15 of 2025
...
Reviewed by: bz, emaste, wulf
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D55176
This commit is contained in:
committed by
Ed Maste
parent
607f6be6ec
commit
5bb0f63020
@@ -43,13 +43,6 @@ struct sysfs_ops {
|
||||
size_t);
|
||||
};
|
||||
|
||||
struct attribute_group {
|
||||
const char *name;
|
||||
mode_t (*is_visible)(struct kobject *,
|
||||
struct attribute *, int);
|
||||
struct attribute **attrs;
|
||||
};
|
||||
|
||||
struct bin_attribute {
|
||||
struct attribute attr;
|
||||
size_t size;
|
||||
@@ -59,6 +52,14 @@ struct bin_attribute {
|
||||
struct bin_attribute *, char *, loff_t, size_t);
|
||||
};
|
||||
|
||||
struct attribute_group {
|
||||
const char *name;
|
||||
mode_t (*is_visible)(struct kobject *,
|
||||
struct attribute *, int);
|
||||
struct attribute **attrs;
|
||||
struct bin_attribute **bin_attrs;
|
||||
};
|
||||
|
||||
#define __ATTR(_name, _mode, _show, _store) { \
|
||||
.attr = { .name = __stringify(_name), .mode = _mode }, \
|
||||
.show = _show, .store = _store, \
|
||||
@@ -370,6 +371,7 @@ static inline int
|
||||
sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
{
|
||||
struct attribute **attr;
|
||||
struct bin_attribute **bin_attr;
|
||||
struct sysctl_oid *oidp;
|
||||
|
||||
/* Don't create the group node if grp->name is undefined. */
|
||||
@@ -378,11 +380,19 @@ sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
OID_AUTO, grp->name, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, grp->name);
|
||||
else
|
||||
oidp = kobj->oidp;
|
||||
for (attr = grp->attrs; *attr != NULL; attr++) {
|
||||
for (attr = grp->attrs; attr != NULL && *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", "");
|
||||
}
|
||||
for (bin_attr = grp->bin_attrs;
|
||||
bin_attr != NULL && *bin_attr != NULL;
|
||||
bin_attr++) {
|
||||
SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
|
||||
(*bin_attr)->attr.name,
|
||||
CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_MPSAFE,
|
||||
kobj, (uintptr_t)*bin_attr, sysctl_handle_bin_attr, "", "");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -434,14 +444,20 @@ static inline void
|
||||
sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp)
|
||||
{
|
||||
struct attribute **attr;
|
||||
struct bin_attribute **bin_attr;
|
||||
struct sysctl_oid *oidp;
|
||||
|
||||
SYSCTL_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp)) {
|
||||
if (strcmp(oidp->oid_name, grp->name) != 0)
|
||||
continue;
|
||||
for (attr = grp->attrs; *attr != NULL; attr++) {
|
||||
for (attr = grp->attrs; attr != NULL && *attr != NULL; attr++) {
|
||||
sysctl_remove_name(oidp, (*attr)->name, 1, 1);
|
||||
}
|
||||
for (bin_attr = grp->bin_attrs;
|
||||
bin_attr != NULL && *bin_attr != NULL;
|
||||
bin_attr++) {
|
||||
sysctl_remove_name(oidp, (*bin_attr)->attr.name, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user