xref: /netbsd-src/share/man/man9/sysmon_envsys.9 (revision 01869ca4d24a86379a68731bf9706a9f0820fe4e)
1.\"	$NetBSD: sysmon_envsys.9,v 1.46 2017/07/03 21:28:48 wiz Exp $
2.\"
3.\" Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Juan Romero Pardines.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
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.
17.\"
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.
29.\"
30.Dd July 13, 2012
31.Dt SYSMON_ENVSYS 9
32.Os
33.Sh NAME
34.Nm sysmon_envsys
35.Nd kernel part of the envsys 2 framework
36.Sh SYNOPSIS
37.In dev/sysmon/sysmonvar.h
38.Ft struct sysmon_envsys *
39.Fn sysmon_envsys_create "void"
40.Ft void
41.Fn sysmon_envsys_destroy "struct sysmon_envsys *"
42.Ft int
43.Fn sysmon_envsys_register "struct sysmon_envsys *"
44.Ft void
45.Fn sysmon_envsys_unregister "struct sysmon_envsys *"
46.Ft int
47.Fn sysmon_envsys_sensor_attach "struct sysmon_envsys *" "envsys_data_t *"
48.Ft int
49.Fn sysmon_envsys_sensor_detach "struct sysmon_envsys *" "envsys_data_t *"
50.Ft void
51.Fn sysmon_envsys_sensor_event "struct sysmon_envsys *" "envsys_data_t *" "int"
52.Ft void
53.Fn sysmon_envsys_foreach_sensor "sysmon_envsys_callback_t" "void *" "bool"
54.Ft int
55.Fn sysmon_envsys_update_limits "struct sysmon_envsys *" "envsys_data_t *"
56.Sh DESCRIPTION
57.Pp
58.Nm
59is the kernel part of the
60.Xr envsys 4
61framework.
62With this framework you are able to register and unregister a
63.Nm
64device, attach or detach sensors into a device, and enable or disable
65automatic monitoring for some sensors without any user interactivity,
66among other things.
67.Ss HOW TO USE THE FRAMEWORK
68To register a new driver to the
69.Nm
70framework, a
71.Em sysmon_envsys
72object must be allocated and initialized; the
73.Fn sysmon_envsys_create
74function is used for this.
75This returns a zero'ed pointer to a
76.Em sysmon_envsys
77structure.
78.Pp
79Once the object has been initialized,
80actual sensors may be initialized and attached (see the
81.Sx SENSOR DETAILS
82section for more information).
83This is accomplished by the
84.Fn sysmon_envsys_sensor_attach
85function, which will attach the
86.Em envsys_data_t
87(a sensor) specified as second argument into the
88.Em sysmon_envsys
89object specified in the first argument.
90.Pp
91Finally, after all sensors have been attached,
92the device needs to set some required (and optional) members of the
93.Em sysmon_envsys
94structure before calling the
95.Fn sysmon_envsys_register
96function to register the device.
97.Pp
98In case of errors during the initialization, the
99.Fn sysmon_envsys_destroy
100function should be used.
101This detaches all previously attached sensors and deallocates the
102.Em sysmon_envsys
103object.
104.Pp
105Some sensors can be monitored, and when the sensor value changes an event
106can be delivered to the
107.Xr powerd 8
108daemon.
109Sensor monitoring can be performed by the
110.Nm
111framework on a polled basis.
112Alternatively, the sensor's device driver can call the
113.Fn sysmon_envsys_sensor_event
114function to deliver the event without waiting for the device to be polled.
115.Pp
116The
117.Fn sysmon_envsys_foreach_sensor
118function can be used by other parts of the kernel to iterate over all
119registered sensors.
120This capability is used by the
121.Xr i386/apm 4
122driver to summarize the state of all battery sensors.
123.Pp
124Drivers can also call the
125.Fn sysmon_envsys_update_limits
126function when it is necessary to reinitialize a sensor's threshold values.
127This is used by the
128.Xr acpibat 4
129driver when a new battery is inserted.
130.Pp
131The
132.Em sysmon_envsys
133structure is defined as follows
134(only the public members are shown):
135.Bd -literal
136struct sysmon_envsys {
137	const char 	*sme_name;
138	int		sme_flags;
139	int		sme_class;
140	uint64_t	sme_events_timeout;
141	void 		*sme_cookie;
142	void (*sme_refresh)(struct sysmon_envsys *, envsys_data_t *);
143	void (*sme_set_limits)(struct sysmon_envsys *, envsys_data_t *,
144			       sysmon_envsys_lim_t *, uint32_t *);
145	void (*sme_get_limits)(struct sysmon_envsys *, envsys_data_t *,
146			       sysmon_envsys_lim_t *, uint32_t *);
147};
148.Ed
149.Pp
150The members have the following meaning:
151.Pp
152.Bl -tag -width "sme_events_timeout"
153.It Fa sme_class
154This specifies the class of the sysmon envsys device.
155See the
156.Sy DEVICE CLASSES
157section for more information (OPTIONAL).
158.It Fa sme_name
159The name that will be used in the driver (REQUIRED).
160.It Fa sme_flags
161Additional flags for the
162.Nm
163device.
164Currently supporting
165.Ar SME_DISABLE_REFRESH .
166If enabled, the
167.Ar sme_refresh
168function callback won't be used
169to refresh sensor data and the driver will use its own method (OPTIONAL).
170.It Fa sme_events_timeout
171This is used to specify the default timeout value (in seconds) that will be
172used to check for critical events if any monitoring flag was set (OPTIONAL).
173.El
174.Pp
175If the driver wants to refresh sensors data via the
176.Nm
177framework, the following members may be specified:
178.Pp
179.Bl -tag -width "sme_events_timeout"
180.It Fa sme_cookie
181Typically a pointer to the device struct (also called
182.Dq softc ) .
183This may be used in the
184.Sy sme_refresh ,
185.Sy sme_get_limits ,
186or
187.Sy sme_set_limits
188function callbacks.
189.It Fa sme_refresh
190Pointer to a function that will be used to refresh sensor data in
191the device.
192This can be used to set the state and other properties of the
193sensor depending on the data returned by the driver.
194.Em NOTE :
195.Em You don't have to refresh all sensors, only the sensor specified by the
196.Sy edata->sensor
197.Em index .
198If this member is not specified, the device driver will be totally
199responsible for all updates of this sensor; the
200.Nm
201framework will not be able to update the sensor value.
202.It Fa sme_get_limits
203Pointer to a function that will be used to obtain from the driver the
204initial limits (or thresholds) used when monitoring a sensor's value.
205(See the
206.Sx SENSOR DETAILS
207section for more information.)
208If this member is not specified, the
209.Dv ENVSYS_FMONLIMITS
210flag will be ignored, and limit monitoring will not occur until
211appropriate limits are enabled from userland via
212.Xr envstat 8 .
213.It Fa sme_set_limits
214Pointer to a function that alerts the device driver whenever monitoring
215limits (or thresholds) are updated by the user.
216Setting this function allows the device driver to reprogram hardware
217limits (if provided by the device) when the user-specificied limits are
218updated, and gives the driver direct control over setting the sensor's
219state based on hardware status.
220.Pp
221The
222.Fa sme_set_limits
223callback can be invoked with the third argument (a pointer to the new
224limits) set to a
225.Dv NULL
226pointer.
227Device drivers must recognize this as a request to restore the sensor
228limits to their original, boot-time values.
229.Pp
230If the
231.Fa sme_set_limits
232member is not specified, the device driver is not informed of changes to
233the sensor's limit values, and the
234.Nm
235framework performs all limit checks in software.
236.El
237.Pp
238Note that it's not necessary to refresh the sensors data before the
239driver is registered, only do it if you need the data in your driver
240to check for a specific condition.
241.Pp
242The timeout value for the monitoring events on a device may be changed via the
243.Dv ENVSYS_SETDICTIONARY
244.Xr ioctl 2
245or the
246.Xr envstat 8
247command.
248.Pp
249To unregister a driver previously registered with the
250.Nm
251framework, the
252.Fn sysmon_envsys_unregister
253function must be used.
254If there were monitoring events registered for the
255driver, they all will be destroyed before the device is unregistered and
256its sensors are detached.
257Finally the
258.Em sysmon_envsys
259object will be freed, so there's no need to call
260.Fn sysmon_envsys_destroy .
261.Ss DEVICE CLASSES
262The
263.Fa sme_class
264member of the
265.Fa sysmon_envsys
266structure is an optional flag that specifies the class of the
267sysmon envsys device.
268Currently there are two classes:
269.Pp
270.Bl -tag -width ident
271.It SME_CLASS_ACADAPTER
272.Pp
273This class is for devices that want to act as an
274.Em AC adapter .
275The device writer must ensure that at least there is a
276sensor with
277.Em units
278of
279.Dv ENVSYS_INDICATOR .
280This will be used to report its current state (on/off).
281.It SME_CLASS_BATTERY
282.Pp
283This class is for devices that want to act as a
284.Em Battery .
285The device writer must ensure that at least there are two sensors with
286units of
287.Dv ENVSYS_BATTERY_CAPACITY
288and
289.Dv ENVSYS_BATTERY_CHARGE .
290.Pp
291These two sensors are used to ensure that the battery device can
292send a
293.Em low-power
294event to the
295.Xr powerd 8
296daemon (if running) when all battery devices are in a critical state.
297(The critical state occurs when a battery is not currently charging
298and its charge state is low or critical.)
299When the
300.Em low-power
301condition is met, an event is sent to the
302.Xr powerd 8
303daemon (if running), which will shutdown the system gracefully
304by executing the
305.Pa /etc/powerd/scripts/sensor_battery
306script.
307.Pp
308If
309.Xr powerd 8
310is not running, the system will be powered off via the
311.Xr cpu_reboot 9
312call with the
313.Dv RB_POWERDOWN
314flag.
315.Pp
316.El
317.Em NOTE :
318If a
319.Dv SME_CLASS_ACADAPTER
320or
321.Dv SME_CLASS_BATTERY
322class device doesn't have the sensors required, the
323.Em low-power
324event will never be sent, and the graceful shutdown won't be possible.
325.Ss SENSOR DETAILS
326Each sensor uses a
327.Sy envsys_data_t
328structure, it's defined as follows (only the public members are shown);
329.Bd -literal
330typedef struct envsys_data {
331	uint32_t	units;
332	uint32_t	state;
333	uint32_t	flags;
334	uint32_t	rpms;
335	int32_t		rfact;
336	int32_t		value_cur;
337	int32_t		value_max;
338	int32_t		value_min;
339	int32_t		value_avg;
340	sysmon_envsys_lim_t limits;
341	int		upropset;
342	char		desc[ENVSYS_DESCLEN];
343} envsys_data_t;
344.Ed
345.Pp
346The members for the
347.Sy envsys_data_t
348structure have the following meaning:
349.Pp
350.Bl -tag -width cdoscdosrunru
351.It Fa units
352Used to set the units type.
353.It Fa state
354Used to set the current state.
355.It Fa flags
356Used to set additional flags.
357Among other uses, if one or more of the
358.Dv ENVSYS_FMONxxx
359flags are set, automatic sensor monitoring will be enabled.
360Periodically, the sensor's value will be checked and if certain
361conditions are met, an event will be sent to the
362.Xr powerd 8
363daemon.
364.Em NOTE
365.Em that limits (or thresholds) can be set at any time to enable
366.Em monitoring that the sensor's value remains within those limits .
367.It Fa rpms
368Used to set the nominal RPM value for
369.Sy fan
370sensors.
371.It Fa rfact
372Used to set the rfact value for
373.Sy voltage
374sensors.
375.It Fa value_cur
376Used to set the current value.
377.It Fa value_max
378Used to set the maximum value.
379.It Fa value_min
380Used to set the minimum value.
381.It Fa value_avg
382Used to set the average value.
383.It Fa limits
384Structure used to contain the sensor's alarm thresholds.
385.It Fa upropset
386Used to keep track of which sensor properties are set.
387.It Fa desc
388Used to set the description string.
389.Em NOTE
390.Em that the description string must be unique in a device, and sensors with
391.Em duplicate or empty description will simply be ignored .
392.El
393.Pp
394Users of this framework must take care about the following points:
395.Bl -bullet
396.It
397The
398.Ar desc
399member needs to have a valid description, unique in a device and non empty
400to be valid.
401.It
402The
403.Ar units
404type must be valid.
405The following units are defined:
406.Pp
407.Bl -tag -width "ENVSYS_BATTERY_CAPACITY" -compact
408.It Dv ENVSYS_STEMP
409For temperature sensors, in microkelvins.
410.It Dv ENVSYS_SFANRPM
411For fan sensors.
412.It Dv ENVSYS_SVOLTS_AC
413For AC Voltage.
414.It Dv ENVSYS_SVOLTS_DC
415For DC Voltage.
416.It Dv ENVSYS_SOHMS
417For Ohms.
418.It Dv ENVSYS_SWATTS
419For Watts.
420.It Dv ENVSYS_SAMPS
421For Ampere.
422.It Dv ENVSYS_SWATTHOUR
423For Watts hour.
424.It Dv ENVSYS_SAMPHOUR
425For Ampere hour.
426.It Dv ENVSYS_INDICATOR
427For sensors that only want a boolean type.
428.It Dv ENVSYS_INTEGER
429For sensors that only want an integer type.
430.It Dv ENVSYS_DRIVE
431For drive sensors.
432.It Dv ENVSYS_BATTERY_CAPACITY
433For Battery device classes.
434This sensor unit uses the
435.Dv ENVSYS_BATTERY_CAPACITY_*
436values in
437.Ar value_cur
438to report its current capacity to userland.
439Mandatory if
440.Fa sme_class
441is set to
442.Dv SME_CLASS_BATTERY .
443.It Dv ENVSYS_BATTERY_CHARGE
444For Battery device classes.
445This sensor is equivalent to the Indicator type, it's a boolean.
446Use it to specify in what state is the Battery state:
447.Sy true
448if the battery is currently charging or
449.Sy false
450otherwise.
451Mandatory if
452.Fa sme_class
453is set to
454.Dv SME_CLASS_BATTERY .
455.El
456.It
457When initializing or refreshing the sensor, the
458.Ar state
459member should be set to a known state (otherwise it will be in
460unknown state).
461Possible values:
462.Pp
463.Bl -tag -width "ENVSYS_SCRITUNDERXX" -compact
464.It Dv ENVSYS_SVALID
465Sets the sensor to a valid state.
466.It Dv ENVSYS_SINVALID
467Sets the sensor to an invalid state.
468.It Dv ENVSYS_SCRITICAL
469Sets the sensor to a critical state.
470.It Dv ENVSYS_SCRITUNDER
471Sets the sensor to a critical under state.
472.It Dv ENVSYS_SCRITOVER
473Sets the sensor to a critical over state.
474.It Dv ENVSYS_SWARNUNDER
475Sets the sensor to a warning under state.
476.It Dv ENVSYS_SWARNOVER
477Sets the sensor to a warning over state.
478.El
479.Pp
480.It
481The
482.Ar flags
483member accepts one or more of the following flags:
484.Pp
485.Bl -tag -width "ENVSYS_FCHANGERFACTXX"
486.It Dv ENVSYS_FCHANGERFACT
487Marks the sensor with ability to change the
488.Ar rfact
489value on the fly (in voltage sensors).
490The
491.Ar rfact
492member must be used in the correct place of the code
493that retrieves and converts the value of the sensor.
494.It Dv ENVSYS_FPERCENT
495This uses the
496.Ar value_cur
497and
498.Ar value_max
499members to make a percentage.
500Both values must be enabled and have data.
501.It Dv ENVSYS_FVALID_MAX
502Marks the
503.Ar value_max
504value as valid.
505.It Dv ENVSYS_FVALID_MIN
506Marks the
507.Ar value_min
508value as valid.
509.It Dv ENVSYS_FVALID_AVG
510Marks the
511.Ar value_avg
512value as valid.
513.It Dv ENVSYS_FMONCRITICAL
514Enables and registers a new event to monitor a critical state.
515.It Dv ENVSYS_FMONLIMITS
516Enables and registers a new event to monitor a sensor's value crossing
517limits or thresholds.
518.It Dv ENVSYS_FMONSTCHANGED
519Enables and registers a new event to monitor battery capacity or drive state
520sensors.
521The flag is not effective if the
522.Ar units
523member is not
524.Dv ENVSYS_DRIVE
525or
526.Dv ENVSYS_BATTERY_CAPACITY .
527.It Dv ENVSYS_FMONNOTSUPP
528Disallows setting of limits (or thresholds) via the
529.Dv ENVSYS_SETDICTIONARY
530.Xr ioctl 2 .
531This flag only disables setting the limits from userland.
532It has no effect on monitoring flags set by the driver.
533.It Dv ENVSYS_FHAS_ENTROPY
534Allows this sensor to provide entropy for
535.Xr rnd 4 .
536.El
537.Pp
538.Em If the driver has to use any of the
539.Ar value_max ,
540.Ar value_min ,
541.Em or
542.Ar value_avg
543.Em members, they should be marked as valid with the appropriate flag .
544.Pp
545.It
546If
547.Ar units
548is set to
549.Dv ENVSYS_DRIVE ,
550the
551.Ar value_cur
552member must be set to one of the following predefined states:
553.Pp
554.Bl -tag -width "ENVSYS_DRIVE_POWERDOWNXX" -compact
555.It Dv ENVSYS_DRIVE_EMPTY
556Drive state is unknown.
557.It Dv ENVSYS_DRIVE_READY
558Drive is ready.
559.It Dv ENVSYS_DRIVE_POWERUP
560Drive is powering up.
561.It Dv ENVSYS_DRIVE_ONLINE
562Drive is online.
563.It Dv ENVSYS_DRIVE_OFFLINE
564Drive is offline.
565.It Dv ENVSYS_DRIVE_IDLE
566Drive is idle.
567.It Dv ENVSYS_DRIVE_ACTIVE
568Drive is active.
569.It Dv ENVSYS_DRIVE_BUILD
570Drive is building.
571.It Dv ENVSYS_DRIVE_REBUILD
572Drive is rebuilding.
573.It Dv ENVSYS_DRIVE_POWERDOWN
574Drive is powering down.
575.It Dv ENVSYS_DRIVE_FAIL
576Drive has failed.
577.It Dv ENVSYS_DRIVE_PFAIL
578Drive has been degraded.
579.It Dv ENVSYS_DRIVE_MIGRATING
580Drive is migrating.
581.It Dv ENVSYS_DRIVE_CHECK
582Drive is checking its state.
583.El
584.Pp
585.It
586If
587.Ar units
588is set to
589.Dv ENVSYS_BATTERY_CAPACITY ,
590the
591.Ar value_cur
592member must be set to one of the following predefined capacity states:
593.Pp
594.Bl -tag -width "ENVSYS_BATTERY_CAPACITY_CRITICAL" -compact
595.It Dv ENVSYS_BATTERY_CAPACITY_NORMAL
596Battery charge is normal.
597.It Dv ENVSYS_BATTERY_CAPACITY_CRITICAL
598Battery charge is critical.
599.It Dv ENVSYS_BATTERY_CAPACITY_LOW
600Battery charge is low.
601.It Dv ENVSYS_BATTERY_CAPACITY_WARNING
602Battery charge is on or below the warning capacity.
603.El
604.It
605The
606.Xr envsys 4
607framework expects to have the values converted to
608a unit that can be converted to another one easily.
609That means the user
610should convert the value returned by the driver to the appropriate unit.
611For example voltage sensors to
612.Sy mV ,
613temperature sensors to
614.Sy uK ,
615Watts to
616.Sy mW ,
617Ampere to
618.Sy mA ,
619etc.
620.Pp
621The following types shouldn't need any conversion:
622.Dv ENVSYS_BATTERY_CAPACITY ,
623.Dv ENVSYS_BATTERY_CHARGE ,
624.Dv ENVSYS_INDICATOR ,
625.Dv ENVSYS_INTEGER ,
626and
627.Dv ENVSYS_DRIVE .
628.Pp
629.Em PLEASE NOTE THAT YOU MUST AVOID USING FLOATING POINT OPERATIONS
630.Em IN KERNEL WHEN CONVERTING THE DATA RETURNED BY THE DRIVER TO THE
631.Em APPROPRIATE UNIT, IT'S NOT ALLOWED .
632.Pp
633.El
634.Ss HOW TO ENABLE AUTOMATIC MONITORING IN SENSORS
635The following example illustrates how to enable automatic monitoring
636in a virtual driver for a
637.Em critical
638state in the first sensor
639.Fa ( sc_sensor[0] ) :
640.Pp
641.Bd -literal
642int
643mydriver_initialize_sensors(struct mysoftc *sc)
644{
645	...
646	/* sensor is initialized with a valid state */
647	sc->sc_sensor[0].state = ENVSYS_SVALID;
648
649	/*
650	 * the monitor member must be true to enable
651	 * automatic monitoring.
652	 */
653	sc->sc_sensor[0].monitor = true;
654
655	/* and now we specify the type of the monitoring event */
656	sc->sc_sensor[0].flags |= ENVSYS_FMONCRITICAL;
657	...
658}
659
660int
661mydriver_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
662{
663	struct mysoftc *sc = sme->sme_cookie;
664
665	/* we get current data from the driver */
666	edata->value_cur = sc->sc_getdata();
667
668	/*
669	 * if value is too high, mark the sensor in
670	 * critical state.
671	 */
672	if (edata->value_cur > MYDRIVER_SENSOR0_HIWAT) {
673		edata->state = ENVSYS_SCRITICAL;
674		/* a critical event will be sent now automatically */
675	} else {
676		/*
677		 * if value is within the limits, and we came from
678		 * a critical state make sure to change sensor's state
679		 * to valid.
680		 */
681		edata->state = ENVSYS_SVALID;
682	}
683	...
684}
685.Ed
686.Sh CODE REFERENCES
687The
688.Sy envsys 2
689framework is implemented within the files:
690.Pp
691.Pa sys/dev/sysmon/sysmon_envsys.c
692.Pp
693.Pa sys/dev/sysmon/sysmon_envsys_events.c
694.Pp
695.Pa sys/dev/sysmon/sysmon_envsys_tables.c
696.Pp
697.Pa sys/dev/sysmon/sysmon_envsys_util.c
698.Sh SEE ALSO
699.Xr envsys 4 ,
700.Xr envstat 8
701.Sh HISTORY
702The first
703.Em envsys
704framework first appeared in
705.Nx 1.5 .
706The
707.Em envsys 2
708framework first appeared in
709.Nx 5.0 .
710.Sh AUTHORS
711The (current)
712.Em envsys 2
713framework was implemented by
714.An Juan Romero Pardines .
715Additional input on the design was provided by many
716.Nx
717developers around the world.
718.Pp
719The first
720.Em envsys
721framework was implemented by
722Jason R. Thorpe, Tim Rightnour, and Bill Squier.
723