1 .\" $NetBSD: sysmon_envsys.9,v 1.30 2009/06/15 12:21:33 wiz Exp $
3 .\" Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
4 .\" All rights reserved.
6 .\" This code is derived from software contributed to The NetBSD Foundation
7 .\" by Juan Romero Pardines.
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
12 .\" 1. Redistributions of source code must retain the above copyright
13 .\" notice, this list of conditions and the following disclaimer.
14 .\" 2. Redistributions in binary form must reproduce the above copyright
15 .\" notice, this list of conditions and the following disclaimer in the
16 .\" documentation and/or other materials provided with the distribution.
18 .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 .\" POSSIBILITY OF SUCH DAMAGE.
35 .Nd kernel part of the envsys 2 framework
37 .In dev/sysmon/sysmonvar.h
38 .Ft struct sysmon_envsys *
39 .Fn sysmon_envsys_create "void"
41 .Fn sysmon_envsys_destroy "struct sysmon_envsys *"
43 .Fn sysmon_envsys_register "struct sysmon_envsys *"
45 .Fn sysmon_envsys_unregister "struct sysmon_envsys *"
47 .Fn sysmon_envsys_sensor_attach "struct sysmon_envsys *" "envsys_data_t *"
49 .Fn sysmon_envsys_sensor_detach "struct sysmon_envsys *" "envsys_data_t *"
53 is the kernel part of the
56 With this framework you are able to register and unregister a
58 device, attach or detach sensors into a device and enable or disable
59 automatic monitoring for some sensors without any user interactivity,
61 .Ss HOW TO USE THE FRAMEWORK
62 To register a new driver to the
66 object must be allocated and initialized; the
67 .Fn sysmon_envsys_create
68 function is used for this.
69 This returns a zero'ed pointer to a sysmon_envsys
70 structure and takes care of initialization of some private features.
72 Once we have the object we could start initializing sensors (see the
74 section for more information) and attaching
75 them to the device, this is accomplished by the
76 .Fn sysmon_envsys_sensor_attach
78 This function attaches the envsys_data_t (sensor) specified
79 as second argument into the sysmon_envsys object specified in the
82 Finally when the sensors are already attached, the device needs to set
83 some required (and optional) members of the sysmon_envsys struct before
85 .Fn sysmon_envsys_register
86 function to register the device.
88 If there's some error before registering the device, the
89 .Fn sysmon_envsys_destroy
90 function must be used to detach the sensors previously attached
91 and free the sysmon_envsys object allocated by the
92 .Fn sysmon_envsys_create
97 structure is defined as follows
98 (only the public members are shown):
100 struct sysmon_envsys {
101 const char *sme_name;
104 uint64_t sme_events_timeout;
106 void (*sme_refresh)(struct sysmon_envsys *, envsys_data_t *);
107 void (*sme_set_limits)(struct sysmon_envsys *, envsys_data_t *,
108 sysmon_envsys_lim_t *);
109 void (*sme_get_limits)(struct sysmon_envsys *, envsys_data_t *,
110 sysmon_envsys_lim_t *);
114 The members have the following meaning:
116 .Bl -tag -width "sme_sensor_data_xxxxxxxxx"
118 This specifies the class of the sysmon envsys device.
121 section for more information (OPTIONAL).
123 The name that will be used in the driver (REQUIRED).
125 Additional flags for the
129 .Ar SME_DISABLE_REFRESH .
132 function callback won't be used
133 to refresh sensors data and the driver will use its own method (OPTIONAL).
134 .It Fa sme_events_timeout
135 This is used to specify the default timeout value (in seconds) that will be
136 used to check for critical events if any monitoring flag was set (OPTIONAL).
139 If the driver wants to refresh sensors data via the
141 framework, the following members may be specified:
143 .Bl -tag -width "sme_sensor_data_xxxxxxxxx"
145 Pointer to the device struct (also called
147 This may be used in the
154 Pointer to a function that will be used to refresh sensor data in
156 This can be used to set the state and other properties of the
157 sensor depending on the data returned by the driver.
159 .Em You don't have to refresh all sensors, only the sensor specified by the
160 .Sy edata-\*[Gt]sensor
162 If this member is not specified, the device driver will be totally
163 responsible for all updates of this sensor; the
165 framework will not be able to update the sensor value.
166 .It Fa sme_get_limits
167 Pointer to a function that will be used to obtain from the driver the
168 initial limits (or thresholds) used when monitoring a sensor's value.
171 section for more information.)
172 If this member is not specified, the
173 .Dv ENVSYS_FMONLIMITS
174 flag will be ignored, and limit monitoring will not occur until
175 appropriate limits are enabled from userland via
177 .It Fa sme_set_limits
178 Pointer to a function that alerts the device driver whenever monitoring
179 limits (or thresholds) are updated by the user.
180 Setting this function allows the device driver to reprogram hardware
181 limits (if provided by the device), and gives the driver direct control
182 over setting the sensor's state based on hardware status.
183 If this member is not specified, the
185 framework performs all limit checks in software.
188 Note that it's not necessary to refresh the sensors data before the
189 driver is registered, only do it if you need the data in your driver
190 to check for a specific condition.
192 The timeout value for the monitoring events on a device may be changed via the
193 .Dv ENVSYS_SETDICTIONARY
199 To unregister a driver previously registered with the
202 .Fn sysmon_envsys_unregister
203 function must be used.
204 If there were monitoring events registered for the
205 driver, they all will be destroyed before the device is unregistered and
206 its sensors will be detached; finally the
208 object will be freed, so there's no need to call
209 .Fn sysmon_envsys_destroy
210 if we are going to unregister a device.
216 structure is an optional flag that specifies the class of the
217 sysmon envsys device.
218 Currently there are two classes:
220 .Bl -tag -width ident
221 .It SME_CLASS_ACADAPTER
223 This class is for devices that want to act as an
225 The device writer must ensure that at least there is a
229 .Dv ENVSYS_INDICATOR .
230 This will be used to report its current state (on/off).
231 .It SME_CLASS_BATTERY
233 This class is for devices that want to act as a
235 The device writer must ensure that at least there are two sensors with
237 .Dv ENVSYS_BATTERY_CAPACITY
239 .Dv ENVSYS_BATTERY_CHARGE .
241 These two sensors are used to ensure that the battery device can
246 daemon (if running) when all battery devices are in a critical state.
247 (The critical state occurs when a battery is not currently charging
248 and its charge state is low or critical).
251 condition is met, an event is sent to the
253 daemon (if running) and will shutdown the system gracefully via the
254 .Fa /etc/powerd/scripts/sensor_battery
259 is not running, the system will be powered off via the
268 .Dv SME_CLASS_ACADAPTER
270 .Dv SME_CLASS_BATTERY
271 class device doesn't have the sensors required, the
273 event will never be sent, and the graceful shutdown won't be possible.
277 structure, it's defined as follows (only the public members are shown);
279 typedef struct envsys_data {
290 char desc[ENVSYS_DESCLEN];
296 structure have the following meaning:
298 .Bl -tag -width cdoscdosrunru
300 Used to set the units type.
302 Used to set the current state.
304 Used to set additional flags.
306 Used to set the nominal RPM value for
310 Used to set the rfact value for
314 Used to set the current value.
316 Used to set the maximum value.
318 Used to set the minimum value.
320 Used to set the average value.
322 Used to enable automatic sensor monitoring (by default
324 The automatic sensor monitoring will check if
325 a condition is met periodically and will send an event to the
328 The monitoring event will be registered when this flag is
330 and one or more of the
332 flags were set in the
336 .Em that limits (or thresholds) can be set at any time to enable
337 .Em monitoring that the sensor's value remains within those limits.
339 Used to set the description string.
341 .Em that the description string must be unique in a device, and sensors with
342 .Em duplicate or empty description will simply be ignored .
345 Users of this framework must take care about the following points:
350 member needs to have a valid description, unique in a device and non empty
356 The following units are defined:
358 .Bl -tag -width "ENVSYS_BATTERY_CAPACITY" -compact
360 For temperature sensors.
361 .It Dv ENVSYS_SFANRPM
363 .It Dv ENVSYS_SVOLTS_AC
365 .It Dv ENVSYS_SVOLTS_DC
373 .It Dv ENVSYS_SWATTHOUR
375 .It Dv ENVSYS_SAMPHOUR
377 .It Dv ENVSYS_INDICATOR
378 For sensors that only want a boolean type.
379 .It Dv ENVSYS_INTEGER
380 For sensors that only want an integer type.
383 .It Dv ENVSYS_BATTERY_CAPACITY
384 For Battery device classes.
385 This sensor unit uses the
386 .Dv ENVSYS_BATTERY_CAPACITY_*
389 to report its current capacity to userland.
393 .Dv SME_CLASS_BATTERY .
394 .It Dv ENVSYS_BATTERY_CHARGE
395 For Battery device classes.
396 This sensor is equivalent to the Indicator type, it's a boolean.
397 Use it to specify in what state is the Battery state:
399 if the battery is currently charging or
405 .Dv SME_CLASS_BATTERY .
408 When initializing or refreshing the sensor, the
410 member should be set to a known state (otherwise it will be in
414 .Bl -tag -width "ENVSYS_SCRITUNDERXX" -compact
416 Sets the sensor to a valid state.
417 .It Dv ENVSYS_SINVALID
418 Sets the sensor to an invalid state.
419 .It Dv ENVSYS_SCRITICAL
420 Sets the sensor to a critical state.
421 .It Dv ENVSYS_SCRITUNDER
422 Sets the sensor to a critical under state.
423 .It Dv ENVSYS_SCRITOVER
424 Sets the sensor to a critical over state.
425 .It Dv ENVSYS_SWARNUNDER
426 Sets the sensor to a warning under state.
427 .It Dv ENVSYS_SWARNOVER
428 Sets the sensor to a warning over state.
434 member accepts one or more of the following flags:
436 .Bl -tag -width "ENVSYS_FCHANGERFACTXX"
437 .It Dv ENVSYS_FCHANGERFACT
438 Marks the sensor with ability to change the
440 value on the fly (in voltage sensors).
443 member must be used in the correct place of the code
444 that retrieves and converts the value of the sensor.
445 .It Dv ENVSYS_FPERCENT
450 members to make a percentage.
451 Both values must be enabled and have data.
452 .It Dv ENVSYS_FVALID_MAX
456 .It Dv ENVSYS_FVALID_MIN
460 .It Dv ENVSYS_FVALID_AVG
464 .It Dv ENVSYS_FMONCRITICAL
465 Enables and registers a new event to monitor a critical state.
466 .It Dv ENVSYS_FMONLIMITS
467 Enables and registers a new event to monitor a sensor's value crossing
468 limits or thresholds.
469 .It Dv ENVSYS_FMONSTCHANGED
470 Enables and registers a new event to monitor Battery capacity or drive state
472 It won't be effective if the
477 .Dv ENVSYS_BATTERY_CAPACITY .
478 .It Dv ENVSYS_FMONNOTSUPP
479 Disallows setting of limits (or thresholds) via the
480 .Dv ENVSYS_SETDICTIONARY
482 This flag has no effect on monitoring flags set in the driver and is
483 only disables setting the limits from userland.
486 .Em If the driver has to use any of the
491 .Em members, they should be marked as valid with the appropriate flag .
500 member must be set to one of the following predefined states:
502 .Bl -tag -width "ENVSYS_DRIVE_POWERDOWNXX" -compact
503 .It Dv ENVSYS_DRIVE_EMPTY
504 Drive state is unknown.
505 .It Dv ENVSYS_DRIVE_READY
507 .It Dv ENVSYS_DRIVE_POWERUP
508 Drive is powering up.
509 .It Dv ENVSYS_DRIVE_ONLINE
511 .It Dv ENVSYS_DRIVE_OFFLINE
513 .It Dv ENVSYS_DRIVE_IDLE
515 .It Dv ENVSYS_DRIVE_ACTIVE
517 .It Dv ENVSYS_DRIVE_BUILD
519 .It Dv ENVSYS_DRIVE_REBUILD
521 .It Dv ENVSYS_DRIVE_POWERDOWN
522 Drive is powering down.
523 .It Dv ENVSYS_DRIVE_FAIL
525 .It Dv ENVSYS_DRIVE_PFAIL
526 Drive has been degraded.
527 .It Dv ENVSYS_DRIVE_MIGRATING
529 .It Dv ENVSYS_DRIVE_CHECK
530 Drive is checking its state.
537 .Dv ENVSYS_BATTERY_CAPACITY ,
540 member must be set to one of the following predefined capacity states:
542 .Bl -tag -width "ENVSYS_BATTERY_CAPACITY_CRITICAL" -compact
543 .It Dv ENVSYS_BATTERY_CAPACITY_NORMAL
544 Battery charge is in normal capacity.
545 .It Dv ENVSYS_BATTERY_CAPACITY_CRITICAL
546 Battery charge is in critical capacity.
547 .It Dv ENVSYS_BATTERY_CAPACITY_LOW
548 Battery charge is in low capacity.
549 .It Dv ENVSYS_BATTERY_CAPACITY_WARNING
550 Battery charge is in warning capacity.
555 framework expects to have the values converted to
556 a unit that can be converted to another one easily.
558 should convert the value returned by the driver to the appropriate unit.
559 For example voltage sensors to
561 temperature sensors to
569 The following types shouldn't need any conversion:
570 .Dv ENVSYS_BATTERY_CAPACITY ,
571 .Dv ENVSYS_BATTERY_CHARGE ,
572 .Dv ENVSYS_INDICATOR ,
577 .Em PLEASE NOTE THAT YOU MUST AVOID USING FLOATING POINT OPERATIONS
578 .Em IN KERNEL WHEN CONVERTING THE DATA RETURNED BY THE DRIVER TO THE
579 .Em APPROPRIATE UNIT, IT'S NOT ALLOWED .
582 .Ss HOW TO ENABLE AUTOMATIC MONITORING IN SENSORS
583 The following example illustrates how to enable automatic monitoring
584 in a virtual driver for a
586 state in the first sensor
587 .Fa ( sc_sensor[0] ) :
591 mydriver_initialize_sensors(struct mysoftc *sc)
594 /* sensor is initialized with a valid state */
595 sc-\*[Gt]sc_sensor[0].state = ENVSYS_SVALID;
598 * the monitor member must be true to enable
599 * automatic monitoring.
601 sc-\*[Gt]sc_sensor[0].monitor = true;
603 /* and now we specify the type of the monitoring event */
604 sc-\*[Gt]sc_sensor[0].flags |= ENVSYS_FMONCRITICAL;
609 mydriver_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
611 struct mysoftc *sc = sme-\*[Gt]sme_cookie;
613 /* we get current data from the driver */
614 edata-\*[Gt]value_cur = sc-\*[Gt]sc_getdata();
617 * if value is too high, mark the sensor in
620 if (edata-\*[Gt]value_cur \*[Gt] MYDRIVER_SENSOR0_HIWAT) {
621 edata-\*[Gt]state = ENVSYS_SCRITICAL;
622 /* a critical event will be sent now automatically */
625 * if value is within the limits, and we came from
626 * a critical state make sure to change sensor's state
629 edata-\*[Gt]state = ENVSYS_SVALID;
635 This section describes places within the
637 source tree where actual code implementing the
639 framework can be found.
640 All pathnames are relative to
645 framework is implemented within the files:
647 .Pa sys/dev/sysmon/sysmon_envsys.c
649 .Pa sys/dev/sysmon/sysmon_envsys_events.c
651 .Pa sys/dev/sysmon/sysmon_envsys_tables.c
653 .Pa sys/dev/sysmon/sysmon_envsys_util.c
660 framework first appeared in
664 framework first appeared in
669 framework was implemented by
670 .An Juan Romero Pardines .
671 Additional input on the design was provided by many
673 developers around the world.
677 framework was implemented by Jason R. Thorpe, Tim Rightnour