Commit 2ed42633 authored by Hans de Goede's avatar Hans de Goede Committed by Mark M. Hoffman

hwmon: update sysfs interface document - error handling

Here is a patch adding some text to the sysfs interface documentation on how
settings written to sysfs attributes should be handled, focussing mainly on
error handling. This version incorperates Jean's latest comments.
Signed-off-by: default avatarHans de Goede <j.w.r.degoede@hhs.nl>
Acked-by: default avatarJean Delvare <khali@linux-fr.org>
Signed-off-by: default avatarMark M. Hoffman <mhoffman@lightlink.com>
parent cc28a610
...@@ -67,6 +67,10 @@ between readings to be caught and alarmed. The exact definition of an ...@@ -67,6 +67,10 @@ between readings to be caught and alarmed. The exact definition of an
alarm (for example, whether a threshold must be met or must be exceeded alarm (for example, whether a threshold must be met or must be exceeded
to cause an alarm) is chip-dependent. to cause an alarm) is chip-dependent.
When setting values of hwmon sysfs attributes, the string representation of
the desired value must be written, note that strings which are not a number
are interpreted as 0! For more on how written strings are interpreted see the
"sysfs attribute writes interpretation" section at the end of this file.
------------------------------------------------------------------------- -------------------------------------------------------------------------
...@@ -411,3 +415,57 @@ beep_mask Bitmask for beep. ...@@ -411,3 +415,57 @@ beep_mask Bitmask for beep.
use discouraged for the same reason. Use individual use discouraged for the same reason. Use individual
*_beep files instead. *_beep files instead.
RW RW
sysfs attribute writes interpretation
-------------------------------------
hwmon sysfs attributes always contain numbers, so the first thing to do is to
convert the input to a number, there are 2 ways todo this depending whether
the number can be negative or not:
unsigned long u = simple_strtoul(buf, NULL, 10);
long s = simple_strtol(buf, NULL, 10);
With buf being the buffer with the user input being passed by the kernel.
Notice that we do not use the second argument of strto[u]l, and thus cannot
tell when 0 is returned, if this was really 0 or is caused by invalid input.
This is done deliberately as checking this everywhere would add a lot of
code to the kernel.
Notice that it is important to always store the converted value in an
unsigned long or long, so that no wrap around can happen before any further
checking.
After the input string is converted to an (unsigned) long, the value should be
checked if its acceptable. Be careful with further conversions on the value
before checking it for validity, as these conversions could still cause a wrap
around before the check. For example do not multiply the result, and only
add/subtract if it has been divided before the add/subtract.
What to do if a value is found to be invalid, depends on the type of the
sysfs attribute that is being set. If it is a continuous setting like a
tempX_max or inX_max attribute, then the value should be clamped to its
limits using SENSORS_LIMIT(value, min_limit, max_limit). If it is not
continuous like for example a tempX_type, then when an invalid value is
written, -EINVAL should be returned.
Example1, temp1_max, register is a signed 8 bit value (-128 - 127 degrees):
--- begin code ---
long v = simple_strtol(buf, NULL, 10) / 1000;
SENSORS_LIMIT(v, -128, 127);
/* write v to register */
--- end code ---
Example2, fan divider setting, valid values 2, 4 and 8:
--- begin code ---
unsigned long v = simple_strtoul(buf, NULL, 10);
switch (v) {
case 2: v = 1; break;
case 4: v = 2; break;
case 8: v = 3; break;
default:
return -EINVAL;
}
/* write v to register */
--- end code ---
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