XenevaOS
Loading...
Searching...
No Matches
sysfs.h
Go to the documentation of this file.
1#ifndef __LINUX_SYSFS_H__
2#define __LINUX_SYSFS_H__
3
4/*
5 * DCL <linux/sysfs.h> -- the two attribute structs and the __ATTR family.
6 *
7 * mainline splits this across sysfs.h and device.h; DCL has no kobject layer,
8 * so what is here is only what a ported driver *declares*: a static
9 * device_attribute produced by DEVICE_ATTR_RW() and a static attribute_group
10 * to hang it in (8250_port.c:3089-3097). Nothing creates a sysfs file from
11 * them yet -- registration goes through uart_port.attr_group, whose consumer
12 * is the stage that brings uart_add_one_port over.
13 *
14 * struct attribute is mainline's two members verbatim (the lockdep fields are
15 * behind CONFIG_DEBUG_LOCK_ALLOC, which DCL does not set). struct
16 * attribute_group is deliberately shorter: see the comment inside it.
17 *
18 * upstream include/linux/sysfs.h (mainline v7.2)
19 */
20
21#include <linux/kernel.h> /* umode_t, size_t */
22
23struct attribute {
24 const char *name;
26#ifdef CONFIG_DEBUG_LOCK_ALLOC
27 bool ignore_lockdep:1;
28 struct lock_class_key *key;
29 struct lock_class_key skey;
30#endif
31};
32
34 const char *name;
35 /* NULL-terminated. 8250_port.c:3096 initialises this one field with a
36 * designated initializer, and uart_port.attr_group points at the group
37 * from outside -- so the member is named and typed exactly as mainline's
38 * union arm names it, while the rest of mainline's group (is_visible,
39 * bin_attrs, bin_size) is not carried: no DCL caller supplies them. */
40 struct attribute **attrs;
41};
42
43/*
44 * __ATTR(_name, _mode, _show, _store) -- mainline's, minus
45 * VERIFY_OCTAL_PERMISSIONS(): DCL has no permission checker to run the mode
46 * through, and a mode that gets through unverified is what mainline's macro
47 * produces on a kernel without that check too.
48 *
49 * The stringification is #_name rather than mainline's __stringify(_name);
50 * both produce "rx_trig_bytes" for the only call in the tree, and DCL's
51 * stringify lives in a header this one does not need to pull in.
52 */
53#define __ATTR(_name, _mode, _show, _store) {\
54 .attr = { .name = #_name, .mode = _mode },\
55 .show = _show,\
56 .store = _store,\
57}
58
59#define __ATTR_RW_MODE(_name, _mode) \
60 __ATTR(_name, _mode, _name##_show, _name##_store)
61#define __ATTR_RW(_name) __ATTR_RW_MODE(_name, 0644)
62
63
64/*
65 * sysfs_emit(buf, fmt, ...) -- write a formatted string into a sysfs buffer.
66 *
67 * mainline bounds by PAGE_SIZE, which is the contract sysfs gives the show
68 * callback: the buffer is always one page. DCL's PAGE_SIZE lives in
69 * <Mm/vmmngr.h>, and pulling the MM header into a sysfs header to read one
70 * constant would be a poor trade, so the bound is spelled out and the reason
71 * is here: 4096 is DCL's page size on every target in scope (Mm/vmmngr.h:90),
72 * and _snprintf additionally caps at _print.c's MAX_STRING_LENGTH, so the
73 * bound is not the only thing standing between this and an overrun.
74 *
75 * One caller: rx_trig_bytes_show at 8250_port.c:3033, writing "%d\n".
76 */
77#define sysfs_emit(buf, fmt, ...) \
78 snprintf((buf), 4096, (fmt), ##__VA_ARGS__)
79
80/*
81 * __ATTR_RO / __ATTR_WO -- the read-only and write-only halves of __ATTR.
82 *
83 * They cannot be written as __ATTR(_name, 0444, _name##_show, _name##_store),
84 * because no store function exists for them to name: __ATTR's expansion
85 * embeds `_store` directly in a struct initialiser, so the macro would fail
86 * at the *declaration*, not at a call site. Hence the three separate
87 * spellings mainline uses too.
88 *
89 * The modes are mainline's -- 0444 for a show-only attribute, 0200 for a
90 * store-only one -- and unlike __ATTR these skip the octal permission check
91 * for the same reason __ATTR does: DCL has no VERIFY_OCTAL_PERMISSIONS.
92 */
93#define __ATTR_RO(_name) { \
94 .attr = { .name = #_name, .mode = 0444 }, \
95 .show = _name##_show, \
96}
97
98#define __ATTR_WO(_name) { \
99 .attr = { .name = #_name, .mode = 0200 }, \
100 .store = _name##_store, \
101}
102
103/*
104 * S_IRUGO -- 0444, "world-readable". mainline defines the whole S_I* family
105 * in <uapi/linux/stat.h>, which this tree has no copy of: nothing needed a
106 * permission *name*, because DEVICE_ATTR_RW()/__ATTR_RO() spell their modes
107 * as literals (0644, 0444). virtio_console.c:1250 is the first caller that
108 * names one -- `static DEVICE_ATTR(name, S_IRUGO, show_port_name, NULL);` --
109 * so the constant is defined here, next to the __ATTR that consumes it, with
110 * mainline's value. S_IWUSR (0200) is spelled out by __ATTR_WO already.
111 */
112#define S_IRUGO 0444
113
114/*
115 * sysfs_create_group() / sysfs_remove_group() -- macros, not functions, and
116 * the reason is worth the whole block.
117 *
118 * DCL/linux_cdev_shim.c used to define these as ordinary functions taking
119 * `const void*`. That works until a mainline caller writes
120 *
121 * err = sysfs_create_group(&port->dev->kobj, &port_attribute_group);
122 * (virtio_console.c:1642)
123 *
124 * because the *argument* still has to parse, and `port->dev->kobj` is a member
125 * that does not exist: <linux/fs.h>'s struct device (the one file this tree
126 * must not edit) carries `kobj_name` at offset 0 -- the slot mainline's
127 * kobj.name occupies -- and no `kobj`. Making struct device grow one is not
128 * available, and rewriting the vendored source is what this tree avoids.
129 *
130 * A macro whose parameters never appear in its replacement list never parses
131 * them. The preprocessor substitutes the whole invocation with `0` and
132 * `&port->dev->kobj` never reaches the parser at all -- which is exactly how
133 * this header's spinlock sibling already handles a lock it does not take
134 * (`#define spin_lock(l) do {} while (0)`, spinlock.h:36).
135 *
136 * The behaviour is unchanged, because the function being replaced was itself
137 * a no-op: "no sysfs tree; success keeps add_port() on the happy path". A
138 * caller that branches on the result still sees 0 (success), and
139 * sysfs_remove_group() still does nothing -- there is no group to remove.
140 */
141#define sysfs_create_group(dev, grp) (0)
142#define sysfs_remove_group(dev, grp) ((void)0)
143/*
144 * The same deal for the drm class links, drm_drv.c:1009/:1034:
145 *
146 * ret = sysfs_create_link(minor->kdev->kobj.parent, &minor->kdev->kobj, name);
147 *
148 * ->kobj does not exist on this build's struct device (see the group
149 * comment above), the parameters never parse, and there is no sysfs tree
150 * to link into -- sysfs_create_link() answered 0 for every real caller
151 * upstream that had no bus to begin with, so 0 here keeps the "primary
152 * node is registered" branch taken. remove is a statement-expression
153 * free no-op for the matching teardown.
154 */
155#define sysfs_create_link(parent, target, name) (0)
156#define sysfs_remove_link(parent, name) ((void)0)
157
158#endif /* __LINUX_SYSFS_H__ */
unsigned int umode_t
Definition kernel.h:58
Definition sysfs.h:33
struct attribute ** attrs
Definition sysfs.h:40
const char * name
Definition sysfs.h:34
Definition sysfs.h:23
const char * name
Definition sysfs.h:24
umode_t mode
Definition sysfs.h:25
Definition lockdep.h:160