1.\" $NetBSD: sysmon_envsys.9,v 1.33 2010/02/25 12:58:18 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 February 25, 2010 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 follows 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 *, uint32_t *); 109 void (*sme_get_limits)(struct sysmon_envsys *, envsys_data_t *, 110 sysmon_envsys_lim_t *, uint32_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 follows (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 sysmon_envsys_lim_t limits; 290 int upropset; 291 bool monitor; 292 char desc[ENVSYS_DESCLEN]; 293} envsys_data_t; 294.Ed 295.Pp 296The members for the 297.Sy envsys_data_t 298structure have the following meaning: 299.Pp 300.Bl -tag -width cdoscdosrunru 301.It Fa units 302Used to set the units type. 303.It Fa state 304Used to set the current state. 305.It Fa flags 306Used to set additional flags. 307.It Fa rpms 308Used to set the nominal RPM value for 309.Sy fan 310sensors. 311.It Fa rfact 312Used to set the rfact value for 313.Sy voltage 314sensors. 315.It Fa value_cur 316Used to set the current value. 317.It Fa value_max 318Used to set the maximum value. 319.It Fa value_min 320Used to set the minimum value. 321.It Fa value_avg 322Used to set the average value. 323.It Fa limits 324Structure used to contain the sensor's alarm thresholds. 325.It Fa upropset 326Used to keep track of which sensor properties are set. 327.It Fa monitor 328Used to enable automatic sensor monitoring (by default 329it's disabled). 330The automatic sensor monitoring will check if 331a condition is met periodically and will send an event to the 332.Xr powerd 8 333daemon (if running). 334The monitoring event will be registered when this flag is 335.Dv true 336and one or more of the 337.Dv ENVSYS_FMONxxx 338flags were set in the 339.Ar flags 340member. 341.Em NOTE 342.Em that limits (or thresholds) can be set at any time to enable 343.Em monitoring that the sensor's value remains within those limits . 344.It Fa desc 345Used to set the description string. 346.Em NOTE 347.Em that the description string must be unique in a device, and sensors with 348.Em duplicate or empty description will simply be ignored . 349.El 350.Pp 351Users of this framework must take care about the following points: 352.Bl -bullet 353.It 354The 355.Ar desc 356member needs to have a valid description, unique in a device and non empty 357to be valid. 358.It 359The 360.Ar units 361type must be valid. 362The following units are defined: 363.Pp 364.Bl -tag -width "ENVSYS_BATTERY_CAPACITY" -compact 365.It Dv ENVSYS_STEMP 366For temperature sensors. 367.It Dv ENVSYS_SFANRPM 368For fan sensors. 369.It Dv ENVSYS_SVOLTS_AC 370For AC Voltage. 371.It Dv ENVSYS_SVOLTS_DC 372For DC Voltage. 373.It Dv ENVSYS_SOHMS 374For Ohms. 375.It Dv ENVSYS_SWATTS 376For Watts. 377.It Dv ENVSYS_SAMPS 378For Ampere. 379.It Dv ENVSYS_SWATTHOUR 380For Watts hour. 381.It Dv ENVSYS_SAMPHOUR 382For Ampere hour. 383.It Dv ENVSYS_INDICATOR 384For sensors that only want a boolean type. 385.It Dv ENVSYS_INTEGER 386For sensors that only want an integer type. 387.It Dv ENVSYS_DRIVE 388For drive sensors. 389.It Dv ENVSYS_BATTERY_CAPACITY 390For Battery device classes. 391This sensor unit uses the 392.Dv ENVSYS_BATTERY_CAPACITY_* 393values in 394.Ar value_cur 395to report its current capacity to userland. 396Mandatory if 397.Fa sme_class 398is set to 399.Dv SME_CLASS_BATTERY . 400.It Dv ENVSYS_BATTERY_CHARGE 401For Battery device classes. 402This sensor is equivalent to the Indicator type, it's a boolean. 403Use it to specify in what state is the Battery state: 404.Sy true 405if the battery is currently charging or 406.Sy false 407otherwise. 408Mandatory if 409.Fa sme_class 410is set to 411.Dv SME_CLASS_BATTERY . 412.El 413.It 414When initializing or refreshing the sensor, the 415.Ar state 416member should be set to a known state (otherwise it will be in 417unknown state). 418Possible values: 419.Pp 420.Bl -tag -width "ENVSYS_SCRITUNDERXX" -compact 421.It Dv ENVSYS_SVALID 422Sets the sensor to a valid state. 423.It Dv ENVSYS_SINVALID 424Sets the sensor to an invalid state. 425.It Dv ENVSYS_SCRITICAL 426Sets the sensor to a critical state. 427.It Dv ENVSYS_SCRITUNDER 428Sets the sensor to a critical under state. 429.It Dv ENVSYS_SCRITOVER 430Sets the sensor to a critical over state. 431.It Dv ENVSYS_SWARNUNDER 432Sets the sensor to a warning under state. 433.It Dv ENVSYS_SWARNOVER 434Sets the sensor to a warning over state. 435.El 436.Pp 437.It 438The 439.Ar flags 440member accepts one or more of the following flags: 441.Pp 442.Bl -tag -width "ENVSYS_FCHANGERFACTXX" 443.It Dv ENVSYS_FCHANGERFACT 444Marks the sensor with ability to change the 445.Ar rfact 446value on the fly (in voltage sensors). 447The 448.Ar rfact 449member must be used in the correct place of the code 450that retrieves and converts the value of the sensor. 451.It Dv ENVSYS_FPERCENT 452This uses the 453.Ar value_cur 454and 455.Ar value_max 456members to make a percentage. 457Both values must be enabled and have data. 458.It Dv ENVSYS_FVALID_MAX 459Marks the 460.Ar value_max 461value as valid. 462.It Dv ENVSYS_FVALID_MIN 463Marks the 464.Ar value_min 465value as valid. 466.It Dv ENVSYS_FVALID_AVG 467Marks the 468.Ar value_avg 469value as valid. 470.It Dv ENVSYS_FMONCRITICAL 471Enables and registers a new event to monitor a critical state. 472.It Dv ENVSYS_FMONLIMITS 473Enables and registers a new event to monitor a sensor's value crossing 474limits or thresholds. 475.It Dv ENVSYS_FMONSTCHANGED 476Enables and registers a new event to monitor Battery capacity or drive state 477sensors. 478It won't be effective if the 479.Ar units 480member is not set to 481.Dv ENVSYS_DRIVE 482or 483.Dv ENVSYS_BATTERY_CAPACITY . 484.It Dv ENVSYS_FMONNOTSUPP 485Disallows setting of limits (or thresholds) via the 486.Dv ENVSYS_SETDICTIONARY 487.Xr ioctl 2 . 488This flag has no effect on monitoring flags set in the driver and is 489only disables setting the limits from userland. 490.El 491.Pp 492.Em If the driver has to use any of the 493.Ar value_max , 494.Ar value_min 495.Em or 496.Ar value_avg 497.Em members, they should be marked as valid with the appropriate flag . 498.Pp 499.It 500If 501.Ar units 502is set to 503.Dv ENVSYS_DRIVE , 504the 505.Ar value_cur 506member must be set to one of the following predefined states: 507.Pp 508.Bl -tag -width "ENVSYS_DRIVE_POWERDOWNXX" -compact 509.It Dv ENVSYS_DRIVE_EMPTY 510Drive state is unknown. 511.It Dv ENVSYS_DRIVE_READY 512Drive is ready. 513.It Dv ENVSYS_DRIVE_POWERUP 514Drive is powering up. 515.It Dv ENVSYS_DRIVE_ONLINE 516Drive is online. 517.It Dv ENVSYS_DRIVE_OFFLINE 518Drive is offline. 519.It Dv ENVSYS_DRIVE_IDLE 520Drive is idle. 521.It Dv ENVSYS_DRIVE_ACTIVE 522Drive is active. 523.It Dv ENVSYS_DRIVE_BUILD 524Drive is building. 525.It Dv ENVSYS_DRIVE_REBUILD 526Drive is rebuilding. 527.It Dv ENVSYS_DRIVE_POWERDOWN 528Drive is powering down. 529.It Dv ENVSYS_DRIVE_FAIL 530Drive has failed. 531.It Dv ENVSYS_DRIVE_PFAIL 532Drive has been degraded. 533.It Dv ENVSYS_DRIVE_MIGRATING 534Drive is migrating. 535.It Dv ENVSYS_DRIVE_CHECK 536Drive is checking its state. 537.El 538.Pp 539.It 540If 541.Ar units 542is set to 543.Dv ENVSYS_BATTERY_CAPACITY , 544the 545.Ar value_cur 546member must be set to one of the following predefined capacity states: 547.Pp 548.Bl -tag -width "ENVSYS_BATTERY_CAPACITY_CRITICAL" -compact 549.It Dv ENVSYS_BATTERY_CAPACITY_NORMAL 550Battery charge is in normal capacity. 551.It Dv ENVSYS_BATTERY_CAPACITY_CRITICAL 552Battery charge is in critical capacity. 553.It Dv ENVSYS_BATTERY_CAPACITY_LOW 554Battery charge is in low capacity. 555.It Dv ENVSYS_BATTERY_CAPACITY_WARNING 556Battery charge is in warning capacity. 557.El 558.It 559The 560.Xr envsys 4 561framework expects to have the values converted to 562a unit that can be converted to another one easily. 563That means the user 564should convert the value returned by the driver to the appropriate unit. 565For example voltage sensors to 566.Sy mV , 567temperature sensors to 568.Sy uK , 569Watts to 570.Sy mW , 571Ampere to 572.Sy mA , 573etc. 574.Pp 575The following types shouldn't need any conversion: 576.Dv ENVSYS_BATTERY_CAPACITY , 577.Dv ENVSYS_BATTERY_CHARGE , 578.Dv ENVSYS_INDICATOR , 579.Dv ENVSYS_INTEGER 580and 581.Dv ENVSYS_DRIVE . 582.Pp 583.Em PLEASE NOTE THAT YOU MUST AVOID USING FLOATING POINT OPERATIONS 584.Em IN KERNEL WHEN CONVERTING THE DATA RETURNED BY THE DRIVER TO THE 585.Em APPROPRIATE UNIT, IT'S NOT ALLOWED . 586.Pp 587.El 588.Ss HOW TO ENABLE AUTOMATIC MONITORING IN SENSORS 589The following example illustrates how to enable automatic monitoring 590in a virtual driver for a 591.Em critical 592state in the first sensor 593.Fa ( sc_sensor[0] ) : 594.Pp 595.Bd -literal 596int 597mydriver_initialize_sensors(struct mysoftc *sc) 598{ 599 ... 600 /* sensor is initialized with a valid state */ 601 sc-\*[Gt]sc_sensor[0].state = ENVSYS_SVALID; 602 603 /* 604 * the monitor member must be true to enable 605 * automatic monitoring. 606 */ 607 sc-\*[Gt]sc_sensor[0].monitor = true; 608 609 /* and now we specify the type of the monitoring event */ 610 sc-\*[Gt]sc_sensor[0].flags |= ENVSYS_FMONCRITICAL; 611 ... 612} 613 614int 615mydriver_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 616{ 617 struct mysoftc *sc = sme-\*[Gt]sme_cookie; 618 619 /* we get current data from the driver */ 620 edata-\*[Gt]value_cur = sc-\*[Gt]sc_getdata(); 621 622 /* 623 * if value is too high, mark the sensor in 624 * critical state. 625 */ 626 if (edata-\*[Gt]value_cur \*[Gt] MYDRIVER_SENSOR0_HIWAT) { 627 edata-\*[Gt]state = ENVSYS_SCRITICAL; 628 /* a critical event will be sent now automatically */ 629 } else { 630 /* 631 * if value is within the limits, and we came from 632 * a critical state make sure to change sensor's state 633 * to valid. 634 */ 635 edata-\*[Gt]state = ENVSYS_SVALID; 636 } 637 ... 638} 639.Ed 640.Sh CODE REFERENCES 641This section describes places within the 642.Nx 643source tree where actual code implementing the 644.Sy envsys 2 645framework can be found. 646All pathnames are relative to 647.Pa /usr/src . 648.Pp 649The 650.Sy envsys 2 651framework is implemented within the files: 652.Pp 653.Pa sys/dev/sysmon/sysmon_envsys.c 654.Pp 655.Pa sys/dev/sysmon/sysmon_envsys_events.c 656.Pp 657.Pa sys/dev/sysmon/sysmon_envsys_tables.c 658.Pp 659.Pa sys/dev/sysmon/sysmon_envsys_util.c 660.Sh SEE ALSO 661.Xr envsys 4 , 662.Xr envstat 8 663.Sh HISTORY 664The first 665.Em envsys 666framework first appeared in 667.Nx 1.5 . 668The 669.Em envsys 2 670framework first appeared in 671.Nx 5.0 . 672.Sh AUTHORS 673The (current) 674.Em envsys 2 675framework was implemented by 676.An Juan Romero Pardines . 677Additional input on the design was provided by many 678.Nx 679developers around the world. 680.Pp 681The first 682.Em envsys 683framework was implemented by Jason R. Thorpe, Tim Rightnour 684and Bill Squier. 685