SYSMON_ENVSYS(9) | Kernel Developer's Manual | SYSMON_ENVSYS(9) |
sysmon_envsys
—
#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 *);
void
sysmon_envsys_sensor_event
(struct
sysmon_envsys *,
envsys_data_t *,
int);
void
sysmon_envsys_foreach_sensor
(sysmon_envsys_callback_t,
void *,
bool);
int
sysmon_envsys_update_limits
(struct
sysmon_envsys *,
envsys_data_t *);
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.
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 sysmon_envsys structure.
Once the object has been initialized, actual sensors may be
initialized and attached (see the
SENSOR DETAILS section for more
information). This is accomplished by the
sysmon_envsys_sensor_attach
() function, which will
attach the envsys_data_t (a sensor) specified as second
argument into the sysmon_envsys object specified in the
first argument.
Finally, after all sensors have been attached, the device needs to
set some required (and optional) members of the
sysmon_envsys structure before calling the
sysmon_envsys_register
() function to register the
device.
In case of errors during the initialization, the
sysmon_envsys_destroy
() function should be used.
This detaches all previously attached sensors and deallocates the
sysmon_envsys object.
Some sensors can be monitored, and when the sensor value changes
an event can be delivered to the
powerd(8) daemon. Sensor
monitoring can be performed by the sysmon_envsys
framework on a polled basis. Alternatively, the sensor's device driver can
call the sysmon_envsys_sensor_event
() function to
deliver the event without waiting for the device to be polled.
The sysmon_envsys_foreach_sensor
()
function can be used by other parts of the kernel to iterate over all
registered sensors. This capability is used by the
i386/apm(4) driver to
summarize the state of all battery sensors.
Drivers can also call the
sysmon_envsys_update_limits
() function when it is
necessary to reinitialize a sensor's threshold values. This is used by the
acpibat(4) driver when a new
battery is inserted.
The sysmon_envsys structure is defined as follows (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 *); void (*sme_set_limits)(struct sysmon_envsys *, envsys_data_t *, sysmon_envsys_lim_t *, uint32_t *); void (*sme_get_limits)(struct sysmon_envsys *, envsys_data_t *, sysmon_envsys_lim_t *, uint32_t *); };
The members have the following meaning:
sysmon_envsys
device.
Currently supporting SME_DISABLE_REFRESH. If
enabled, the sme_refresh function callback won't be
used to refresh sensor data and the driver will use its own method
(OPTIONAL).If the driver wants to refresh sensors data via the
sysmon_envsys
framework, the following members may
be specified:
sysmon_envsys
framework will not be able to update the sensor value.ENVSYS_FMONLIMITS
flag will be ignored, and limit
monitoring will not occur until appropriate limits are enabled from
userland via
envstat(8).The sme_set_limits callback can be
invoked with the third argument (a pointer to the new limits) set to a
NULL
pointer. Device drivers must recognize this
as a request to restore the sensor limits to their original, boot-time
values.
If the sme_set_limits member is not
specified, the device driver is not informed of changes to the sensor's
limit values, and the sysmon_envsys
framework
performs all limit checks in software.
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 are detached.
Finally the sysmon_envsys object will be freed, so there's
no need to call sysmon_envsys_destroy
().
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 current state (on/off).
This class is for devices that want to act as a
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 can send a low-power event to the powerd(8) daemon (if running) when all battery devices are in a critical state. (The critical state occurs when 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), which will shutdown the system gracefully by executing 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 device doesn't have the
sensors required, the low-power event will never be sent,
and the graceful shutdown won't be possible.
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; sysmon_envsys_lim_t limits; int upropset; char desc[ENVSYS_DESCLEN]; } envsys_data_t;
The members for the envsys_data_t structure have the following meaning:
ENVSYS_FMONxxx
flags are set, automatic sensor
monitoring will be enabled. Periodically, the sensor's value will be
checked and if certain conditions are met, an event will be sent to the
powerd(8) daemon.
NOTE that limits (or thresholds) can be
set at any time to enable monitoring that the sensor's
value remains within those limits.Users of this framework must take care about the following points:
ENVSYS_STEMP
ENVSYS_SFANRPM
ENVSYS_SVOLTS_AC
ENVSYS_SVOLTS_DC
ENVSYS_SOHMS
ENVSYS_SWATTS
ENVSYS_SAMPS
ENVSYS_SWATTHOUR
ENVSYS_SAMPHOUR
ENVSYS_INDICATOR
ENVSYS_INTEGER
ENVSYS_DRIVE
ENVSYS_BATTERY_CAPACITY
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
SME_CLASS_BATTERY
.ENVSYS_SVALID
ENVSYS_SINVALID
ENVSYS_SCRITICAL
ENVSYS_SCRITUNDER
ENVSYS_SCRITOVER
ENVSYS_SWARNUNDER
ENVSYS_SWARNOVER
ENVSYS_FCHANGERFACT
ENVSYS_FPERCENT
ENVSYS_FVALID_MAX
ENVSYS_FVALID_MIN
ENVSYS_FVALID_AVG
ENVSYS_FMONCRITICAL
ENVSYS_FMONLIMITS
ENVSYS_FMONSTCHANGED
ENVSYS_DRIVE
or
ENVSYS_BATTERY_CAPACITY
.ENVSYS_FMONNOTSUPP
ENVSYS_SETDICTIONARY
ioctl(2). This flag only
disables setting the limits from userland. It has no effect on
monitoring flags set by the driver.ENVSYS_FHAS_ENTROPY
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 appropriate flag.
ENVSYS_DRIVE
, the value_cur
member must be set to one of the following predefined states:
ENVSYS_DRIVE_EMPTY
ENVSYS_DRIVE_READY
ENVSYS_DRIVE_POWERUP
ENVSYS_DRIVE_ONLINE
ENVSYS_DRIVE_OFFLINE
ENVSYS_DRIVE_IDLE
ENVSYS_DRIVE_ACTIVE
ENVSYS_DRIVE_BUILD
ENVSYS_DRIVE_REBUILD
ENVSYS_DRIVE_POWERDOWN
ENVSYS_DRIVE_FAIL
ENVSYS_DRIVE_PFAIL
ENVSYS_DRIVE_MIGRATING
ENVSYS_DRIVE_CHECK
ENVSYS_BATTERY_CAPACITY
, the
value_cur member must be set to one of the following
predefined capacity states:
ENVSYS_BATTERY_CAPACITY_NORMAL
ENVSYS_BATTERY_CAPACITY_CRITICAL
ENVSYS_BATTERY_CAPACITY_LOW
ENVSYS_BATTERY_CAPACITY_WARNING
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 APPROPRIATE UNIT, IT'S NOT ALLOWED.
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; } ... }
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
The first envsys framework was implemented by Jason R. Thorpe, Tim Rightnour, and Bill Squier.
July 13, 2012 | NetBSD 9.2 |