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