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
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 detachs 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 threshhold 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:
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 sensor data and the driver will use its own method (OPTIONAL).
sme_events_timeout
This is used to specify the default timeout value (in seconds) that will be used to check for critical events if any monitoring flag was set (OPTIONAL).
If the driver wants to refresh sensors data via the
sysmon_envsys framework, the following members may be specified:
sme_cookie
Typically a pointer to the device struct (also called “softc”). This may be used in the sme_refresh, sme_get_limits, or sme_set_limits function callbacks.
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 on the data returned by the driver. NOTE: You don't have to refresh all sensors, only the sensor specified by the edata->sensor index. If this member is not specified, the device driver will be totally responsible for all updates of this sensor; the sysmon_envsys framework will not be able to update the sensor value.
sme_get_limits
Pointer to a function that will be used to obtain from the driver the initial limits (or thresholds) used when monitoring a sensor's value. (See the
SENSOR DETAILS section for more information.) If this member is not specified, the
ENVSYS_FMONLIMITS flag will be ignored, and limit monitoring will not occur until appropriate limits are enabled from userland via
envstat(8).
sme_set_limits
Pointer to a function that alerts the device driver whenever monitoring limits (or thresholds) are updated by the user. Setting this function allows the device driver to reprogram hardware limits (if provided by the device) when the user-specificied limits are updated, and gives the driver direct control over setting the sensor's state based on hardware status.
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().