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