SYSMON_ENVSYS(9)       NetBSD Kernel Developer's Manual       SYSMON_ENVSYS(9)

NAME
     sysmon_envsys -- kernel part of the envsys 2 framework

SYNOPSIS
     #include <dev/sysmon/sysmonvar.h>

     struct sysmon_envsys *
     sysmon_envsys_create(void);

     void
     sysmon_envsys_destroy(struct sysmon_envsys *);

     int
     sysmon_envsys_register(struct sysmon_envsys *);

     void
     sysmon_envsys_unregister(struct sysmon_envsys *);

     int
     sysmon_envsys_sensor_attach(struct sysmon_envsys *, envsys_data_t *);

     int
     sysmon_envsys_sensor_detach(struct sysmon_envsys *, envsys_data_t *);

DESCRIPTION
     sysmon_envsys is the kernel part of the envsys(4) framework.  With this
     framework you are able to register and unregister a sysmon_envsys device,
     attach or detach sensors into a device and enable or disable automatic
     monitoring for some sensors without any user interactivity, among other
     things.

   HOW TO USE THE FRAMEWORK
     To register a new driver to the sysmon_envsys framework, a sysmon_envsys
     object must be allocated and initialized; the sysmon_envsys_create()
     function is used for this. This returns a zero'ed pointer to a sys-
     mon_envsys structure and takes care of initialization of some private
     features.

     Once we have the object we could start initializing sensors (see the
     SENSOR DETAILS section for more information) and attaching them to the
     device, this is acomplished by the sysmon_envsys_sensor_attach() func-
     tion. This function attachs the envsys_data_t (sensor) specified as sec-
     ond argument into the sysmon_envsys object specified in the first argu-
     ment.

     Finally when the sensors are already attached, the device needs to set
     some required (and optional) members of the sysmon_envsys struct before
     calling the sysmon_envsys_register() function to register the device.

     If there's some error before registering the device, the
     sysmon_envsys_destroy() function must be used to detach the sensors pre-
     viously attached and free the sysmon_envsys object allocated by the
     sysmon_envsys_create() function.

     The sysmon_envsys structure is defined as follow (only the public members
     are shown):

     struct sysmon_envsys {
             const char      *sme_name;
             int             sme_flags;
             int             sme_class;
             uint64_t        sme_events_timeout;
             void            *sme_cookie;
             void (*sme_refresh)(struct sysmon_envsys *, envsys_data_t *);
     };

     The members have the following meaning:

     sme_class                  This specifies the class of the sysmon envsys
                                device. See the DEVICE CLASSES section for
                                more information (OPTIONAL).

     sme_name                   The name that will be used in the driver
                                (REQUIRED).

     sme_flags                  Additional flags for the sysmon_envsys device.
                                Currently supporting SME_DISABLE_REFRESH.  If
                                enabled, the sme_refresh function callback
                                won't be used to refresh sensors data and the
                                driver will use its own method.  Hence
                                sme_cookie won't be necessary either
                                (OPTIONAL).

     sme_events_timeout         This is used to specify the default timeout
                                value that will be used to check for critical
                                events if any monitoring flag was set. The
                                value is used as seconds (OPTIONAL).

     If the driver wants to refresh sensors data via the sysmon_envsys frame-
     work, the following members must be specified:

     sme_cookie                 Pointer to the device struct (also called
                                ``softc'' ). This may be used in the
                                sme_refresh function callback.

     sme_refresh                Pointer to a function that will be used to
                                refresh sensor data in the device. This can be
                                used to set the state and other properties of
                                the sensor depending of the returned data by
                                the driver.  NOTE: You don't have to refresh
                                all sensors, only the sensor specified by the
                                edata->sensor index.

     Note that it's not necessary to refresh the sensors data before the
     driver is registered, only do it if you need the data in your driver to
     check for a specific condition.

     The timeout value for the monitoring events on a device may be changed
     via the ENVSYS_SETDICTIONARY ioctl(2) or the envstat(8) command.

     To unregister a driver previously registered with the sysmon_envsys
     framework, the sysmon_envsys_unregister() function must be used. If there
     were monitoring events registered for the driver, they all will be
     destroyed before the device is unregistered and its sensors will be
     detached; finally the sysmon_envsys object will be freed, so there's no
     need to call sysmon_envsys_destroy() if we are going to unregister a
     device.

   DEVICE CLASSES
     The sme_class member of the sysmon_envsys structure is an optional flag
     that specifies the class of the sysmon envsys device. Currently there are
     two classes:

     SME_CLASS_ACADAPTER

            This class is for devices that want to act as an AC adapter.  The
            device writer must ensure that at least there is a sensor with
            units of ENVSYS_INDICATOR.  This will be used to report its cur-
            rent state (on/off).

     SME_CLASS_BATTERY

            This class is for devices that want to act as an Battery.  The
            device writer must ensure that at least there are two sensors with
            units of ENVSYS_BATTERY_CAPACITY and ENVSYS_BATTERY_CHARGE.

            These two sensors are used to ensure that the battery device won't
            never send a low-power event to the powerd(8) daemon (if running)
            when all battery devices are in a critical state.  The critical
            state means that a battery is not currently charging and its
            charge state is low or critical.  When the low-power condition is
            met, an event is sent to the powerd(8) daemon (if running) and
            will shutdown the system gracefully via the
            /etc/powerd/scripts/sensor_battery script.

            If powerd(8) is not running, the system will be powered off via
            the cpu_reboot(9) call with the RB_POWERDOWN flag.

     NOTE: If a SME_CLASS_ACADAPTER or SME_CLASS_BATTERY class don't have the
     sensors required, the low-power event will never be sent, and the grace-
     ful shutdown won't be possible.

   SENSOR DETAILS
     Each sensor uses a envsys_data_t structure, it's defined as follow (only
     the public members are shown);

     typedef struct envsys_data {
             uint32_t        units;
             uint32_t        state;
             uint32_t        flags;
             uint32_t        rpms;
             int32_t         rfact;
             int32_t         value_cur;
             int32_t         value_max;
             int32_t         value_min;
             int32_t         value_avg;
             bool            monitor;
             char            desc[ENVSYS_DESCLEN];
     } envsys_data_t;

     The members for the envsys_data_t structure have the following meaning:

     units          Used to set the units type.

     state          Used to set the current state.

     flags          Used to set additional flags.

     rpms           Used to set the nominal RPM value for fan sensors.

     rfact          Used to set the rfact value for voltage sensors.

     value_cur      Used to set the current value.

     value_max      Used to set the maximum value.

     value_min      Used to set the minimum value.

     value_avg      Used to set the average value.

     monitor        Used to enable automatic sensor monitoring (by default
                    it's disabled). The automatic sensor monitoring will check
                    if a condition is met periodically and will send an event
                    to the powerd(8) daemon (if running). The monitoring event
                    will be registered when this flag is true and one or more
                    of the ENVSYS_FMONFOO flags were set in the flags member.

     desc           Used to set the description string.  NOTE that the
                    description string must be unique in a device, and sensors
                    with duplicate or empty description will simply be
                    ignored.

     Users of this framework must take care about the following points:

     +   The desc member needs to have a valid description, unique in a device
         and non empty to be valid.

     +   The units type must be valid. The following units are defined:

         ENVSYS_STEMP             For temperature sensors.
         ENVSYS_SFANRPM           For fan sensors.
         ENVSYS_SVOLTS_AC         For AC Voltage.
         ENVSYS_SVOLTS_DC         For DC Voltage.
         ENVSYS_SOHMS             For Ohms.
         ENVSYS_SWATTS            For Watts.
         ENVSYS_SAMPS             For Ampere.
         ENVSYS_SWATTHOUR         For Watts hour.
         ENVSYS_SAMPHOUR          For Ampere hour.
         ENVSYS_INDICATOR         For sensors that only want a boolean type.
         ENVSYS_INTEGER           For sensors that only want an integer type.
         ENVSYS_DRIVE             For drive sensors.
         ENVSYS_BATTERY_CAPACITY  For Battery device classes. This sensor unit
                                  uses the ENVSYS_BATTERY_CAPACITY_* values in
                                  value_cur to report its current capacity to
                                  userland. Mandatory if sme_class is set to
                                  SME_CLASS_BATTERY.
         ENVSYS_BATTERY_CHARGE    For Battery device classes. This sensor is
                                  equivalent to the Indicator type, it's a
                                  boolean. Use it to specify in what state is
                                  the Battery state: true if the battery is
                                  currently charging or false otherwise.
                                  Mandatory if sme_class is set to
                                  SME_CLASS_BATTERY.

     +   When initializing or refreshing the sensor, the state member should
         be set to a known state (otherwise it will be in unknown state). Pos-
         sible values:

         ENVSYS_SVALID        Sets the sensor to a valid state.
         ENVSYS_SINVALID      Sets the sensor to an invalid state.
         ENVSYS_SCRITICAL     Sets the sensor to a critical state.
         ENVSYS_SCRITUNDER    Sets the sensor to a critical under state.
         ENVSYS_SCRITOVER     Sets the sensor to a critical over state.
         ENVSYS_SWARNUNDER    Sets the sensor to a warning under state.
         ENVSYS_SWARNOVER     Sets the sensor to a warning over state.

     +   The flags member accepts one or more of the following flags:

         ENVSYS_FCHANGERFACT    Marks the sensor with ability to change the
                                rfact value on the fly (in voltage sensors).
                                The rfact member must be used in the correct
                                place of the code that retrieves and converts
                                the value of the sensor.

         ENVSYS_FPERCENT        This uses the value_cur and value_max members
                                to make a percentage. Both values must be
                                enabled and have data.

         ENVSYS_FVALID_MAX      Marks the value_max value as valid.

         ENVSYS_FVALID_MIN      Marks the value_min value as valid.

         ENVSYS_FVALID_AVG      Marks the value_avg value as valid.

         ENVSYS_FMONCRITICAL    Enables and registers a new event to monitor a
                                critical state.

         ENVSYS_FMONCRITUNDER   Enables and registers a new event to monitor a
                                critical under state.

         ENVSYS_FMONCRITOVER    Enables and registers a new event to monitor a
                                critical over state.

         ENVSYS_FMONWARNUNDER   Enables and registers a new event to monitor a
                                warning under state.

         ENVSYS_FMONWARNOVER    Enables and registers a new event to monitor a
                                warning over state.

         ENVSYS_FMONSTCHANGED   Enables and registers a new event to monitor
                                Battery capacity or drive state sensors. It
                                won't be effective if the units member is not
                                set to ENVSYS_DRIVE or
                                ENVSYS_BATTERY_CAPACITY.

         ENVSYS_FMONNOTSUPP     Disallows to set a critical limit via the
                                ENVSYS_SETDICTIONARY ioctl(2).  This flag has
                                not any effect for monitoring flags set in the
                                driver and it's only meant to disable setting
                                critical limits from userland.

         If the driver has to use any of the value_max, value_min or value_avg
         members, they should be marked as valid with the appropiate flag.

     +   If units is set to ENVSYS_DRIVE, there are some predefined states
         that must be set (only one) to the value_cur member:

         ENVSYS_DRIVE_EMPTY        Drive state is unknown.
         ENVSYS_DRIVE_READY        Drive is ready.
         ENVSYS_DRIVE_POWERUP      Drive is powering up.
         ENVSYS_DRIVE_ONLINE       Drive is online.
         ENVSYS_DRIVE_OFFLINE      Drive is offline.
         ENVSYS_DRIVE_IDLE         Drive is idle.
         ENVSYS_DRIVE_ACTIVE       Drive is active.
         ENVSYS_DRIVE_BUILD        Drive is building.
         ENVSYS_DRIVE_REBUILD      Drive is rebuilding.
         ENVSYS_DRIVE_POWERDOWN    Drive is powering down.
         ENVSYS_DRIVE_FAIL         Drive has failed.
         ENVSYS_DRIVE_PFAIL        Drive has been degraded.
         ENVSYS_DRIVE_MIGRATING    Drive is migrating.
         ENVSYS_DRIVE_CHECK        Drive is checking its state.

     +   If units is set to ENVSYS_BATTERY_CAPACITY, there are some predefined
         capacity states that must be set (only one) to the value_cur member:

         ENVSYS_BATTERY_CAPACITY_NORMAL    Battery charge is in normal capac-
                                           ity.
         ENVSYS_BATTERY_CAPACITY_CRITICAL  Battery charge is in critical
                                           capacity.
         ENVSYS_BATTERY_CAPACITY_LOW       Battery charge is in low capacity.
         ENVSYS_BATTERY_CAPACITY_WARNING   Battery charge is in warning capac-
                                           ity.

     +   The envsys(4) framework expects to have the values converted to a
         unit that can be converted to another one easily. That means the user
         should convert the value returned by the driver to the appropiate
         unit.  For example voltage sensors to mV, temperature sensors to uK,
         Watts to mW, Ampere to mA, etc.

         The following types shouldn't need any conversion:
         ENVSYS_BATTERY_CAPACITY, ENVSYS_BATTERY_CHARGE, ENVSYS_INDICATOR,
         ENVSYS_INTEGER and ENVSYS_DRIVE.

         PLEASE NOTE THAT YOU MUST AVOID USING FLOATING POINT OPERATIONS IN
         KERNEL WHEN CONVERTING THE DATA RETURNED BY THE DRIVER TO THE
         APPROPIATE UNIT, IT'S NOT ALLOWED.

   HOW TO ENABLE AUTOMATIC MONITORING IN SENSORS
     The following example illustrates how to enable automatic monitoring in a
     virtual driver for a critical state in the first sensor (sc_sensor[0]):

     int
     mydriver_initialize_sensors(struct mysoftc *sc)
     {
             ...
             /* sensor is initialized with a valid state */
             sc->sc_sensor[0].state = ENVSYS_SVALID;

             /*
              * the monitor member must be true to enable
              * automatic monitoring.
              */
             sc->sc_sensor[0].monitor = true;

             /* and now we specify the type of the monitoring event */
             sc->sc_sensor[0].flags |= ENVSYS_FMONCRITICAL;
             ...
     }

     int
     mydriver_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
     {
             struct mysoftc *sc = sme->sme_cookie;

             /* we get current data from the driver */
             edata->value_cur = sc->sc_getdata();

             /*
              * if value is too high, mark the sensor in
              * critical state.
              */
             if (edata->value_cur > MYDRIVER_SENSOR0_HIWAT) {
                     edata->state = ENVSYS_SCRITICAL;
                     /* a critical event will be sent now automatically */
             } else {
                     /*
                      * if value is within the limits, and we came from
                      * a critical state make sure to change sensor's state
                      * to valid.
                      */
                     edata->state = ENVSYS_SVALID;
             }
             ...
     }

CODE REFERENCES
     This section describes places within the NetBSD source tree where actual
     code implementing the envsys 2 framework can be found. All pathnames are
     relative to /usr/src.

     The envsys 2 framework is implemented within the files:

     sys/dev/sysmon/sysmon_envsys.c

     sys/dev/sysmon/sysmon_envsys_events.c

     sys/dev/sysmon/sysmon_envsys_tables.c

     sys/dev/sysmon/sysmon_envsys_util.c

     There's an example LKM driver that shows how the framework works in:
     sys/lkm/misc/envsys2/lkminit_envsys2.c.

SEE ALSO
     envsys(4), envstat(8)

HISTORY
     The first envsys framework first appeared in NetBSD 1.5.  The envsys 2
     framework first appeared in NetBSD 5.0.

AUTHORS
     The (current) envsys 2 framework was implemented by Juan Romero Pardines.
     Additional input on the design was provided by many NetBSD developers
     around the world.

     The first envsys framework was implemented by Jason R. Thorpe, Tim Right-
     nour and Bill Squier.

NetBSD 5.1                     February 28, 2008                    NetBSD 5.1

You can also request any man page by name and (optionally) by section:

Command: 
Section: 
Architecture: 
Collection: 
 

Use the DEFAULT collection to view manual pages for third-party software.


©1994 Man-cgi 1.15, Panagiotis Christias
©1996-2019 Modified for NetBSD by Kimmo Suominen