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