Page MenuHomeFreeBSD

D49068.id.diff
No OneTemporary

D49068.id.diff

Index: sys/compat/linuxkpi/common/include/linux/sysfs.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/sysfs.h
+++ sys/compat/linuxkpi/common/include/linux/sysfs.h
@@ -50,6 +50,15 @@
struct attribute **attrs;
};
+struct bin_attribute {
+ struct attribute attr;
+ size_t size;
+ ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
+ char *, loff_t, size_t);
+ ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
+ char *, loff_t, size_t);
+};
+
#define __ATTR(_name, _mode, _show, _store) { \
.attr = { .name = __stringify(_name), .mode = _mode }, \
.show = _show, .store = _store, \
@@ -155,6 +164,82 @@
sysctl_remove_name(kobj->oidp, attr->name, 1, 1);
}
+static inline int
+sysctl_handle_bin_attr(SYSCTL_HANDLER_ARGS)
+{
+ struct kobject *kobj;
+ struct bin_attribute *attr;
+ char *buf;
+ int error;
+ ssize_t len;
+
+ kobj = arg1;
+ attr = (struct bin_attribute *)(intptr_t)arg2;
+ if (kobj->ktype == NULL || kobj->ktype->sysfs_ops == NULL)
+ return (ENODEV);
+ buf = (char *)get_zeroed_page(GFP_KERNEL);
+ if (buf == NULL)
+ return (ENOMEM);
+
+ if (attr->read) {
+ len = attr->read(
+ NULL, /* <-- struct file, unimplemented */
+ kobj, attr, buf, req->oldidx, PAGE_SIZE);
+ if (len < 0) {
+ error = -len;
+ if (error != EIO)
+ goto out;
+ }
+ }
+
+ error = sysctl_handle_string(oidp, buf, PAGE_SIZE, req);
+ if (error != 0 || req->newptr == NULL || attr->write == NULL)
+ goto out;
+
+ len = attr->write(
+ NULL, /* <-- struct file, unimplemented */
+ kobj, attr, buf, req->newidx, req->newlen);
+ if (len < 0)
+ error = -len;
+out:
+ free_page((unsigned long)buf);
+
+ return (error);
+}
+
+static inline int
+sysfs_create_bin_file(struct kobject *kobj, const struct bin_attribute *attr)
+{
+ struct sysctl_oid *oid;
+ int ctlflags;
+
+ ctlflags = CTLTYPE_OPAQUE | CTLFLAG_MPSAFE;
+ if (attr->attr.mode & (S_IRUSR | S_IWUSR)) {
+ ctlflags |= CTLFLAG_RW;
+ } else if (attr->attr.mode & S_IRUSR) {
+ ctlflags |= CTLFLAG_RD;
+ } else if (attr->attr.mode & S_IWUSR) {
+ ctlflags |= CTLFLAG_WR;
+ }
+
+ oid = SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(kobj->oidp), OID_AUTO,
+ attr->attr.name, ctlflags, kobj,
+ (uintptr_t)attr, sysctl_handle_bin_attr, "", "");
+ if (!oid) {
+ return (-ENOMEM);
+ }
+
+ return (0);
+}
+
+static inline void
+sysfs_remove_bin_file(struct kobject *kobj, const struct bin_attribute *attr)
+{
+
+ if (kobj->oidp)
+ sysctl_remove_name(kobj->oidp, attr->attr.name, 1, 1);
+}
+
static inline int
sysfs_create_link(struct kobject *kobj __unused,
struct kobject *target __unused, const char *name __unused)

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 22, 3:53 PM (57 m, 12 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16774357
Default Alt Text
D49068.id.diff (2 KB)

Event Timeline