| 1 | /* $NetBSD: sysmonvar.h,v 1.49 2015/04/23 23:22:03 pgoyette Exp $ */ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 2000 Zembu Labs, Inc. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Author: Jason R. Thorpe <thorpej@zembu.com> |
| 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 Zembu Labs, Inc. |
| 20 | * 4. Neither the name of Zembu Labs nor the names of its employees may |
| 21 | * be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. |
| 23 | * |
| 24 | * THIS SOFTWARE IS PROVIDED BY ZEMBU LABS, INC. ``AS IS'' AND ANY EXPRESS |
| 25 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAR- |
| 26 | * RANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS- |
| 27 | * CLAIMED. IN NO EVENT SHALL ZEMBU LABS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 34 | */ |
| 35 | |
| 36 | #ifndef _DEV_SYSMON_SYSMONVAR_H_ |
| 37 | #define _DEV_SYSMON_SYSMONVAR_H_ |
| 38 | |
| 39 | #include <sys/param.h> |
| 40 | #include <sys/envsys.h> |
| 41 | #include <sys/wdog.h> |
| 42 | #include <sys/power.h> |
| 43 | #include <sys/queue.h> |
| 44 | #include <sys/callout.h> |
| 45 | #include <sys/mutex.h> |
| 46 | #include <sys/condvar.h> |
| 47 | #include <sys/rndsource.h> |
| 48 | |
| 49 | struct lwp; |
| 50 | struct proc; |
| 51 | struct knote; |
| 52 | struct uio; |
| 53 | struct workqueue; |
| 54 | |
| 55 | #define SYSMON_MINOR_ENVSYS 0 |
| 56 | #define SYSMON_MINOR_WDOG 1 |
| 57 | #define SYSMON_MINOR_POWER 2 |
| 58 | |
| 59 | /***************************************************************************** |
| 60 | * Environmental sensor support |
| 61 | *****************************************************************************/ |
| 62 | |
| 63 | /* |
| 64 | * Thresholds/limits that are being monitored |
| 65 | */ |
| 66 | |
| 67 | enum envsys_lims { |
| 68 | ENVSYS_LIM_CRITMAX, |
| 69 | ENVSYS_LIM_WARNMAX, |
| 70 | ENVSYS_LIM_WARNMIN, |
| 71 | ENVSYS_LIM_CRITMIN, |
| 72 | ENVSYS_LIM_LASTLIM |
| 73 | }; |
| 74 | |
| 75 | struct sysmon_envsys_lim { |
| 76 | int32_t critmax; |
| 77 | int32_t warnmax; |
| 78 | int32_t warnmin; |
| 79 | int32_t critmin; |
| 80 | }; |
| 81 | |
| 82 | typedef union { |
| 83 | int32_t sel_limit_list[ENVSYS_LIM_LASTLIM]; |
| 84 | struct sysmon_envsys_lim sel_limits; |
| 85 | } sysmon_envsys_lim_t; |
| 86 | |
| 87 | #define sel_critmax sel_limits.critmax |
| 88 | #define sel_warnmax sel_limits.warnmax |
| 89 | #define sel_warnmin sel_limits.warnmin |
| 90 | #define sel_critmin sel_limits.critmin |
| 91 | |
| 92 | /* struct used by a sensor */ |
| 93 | struct envsys_data { |
| 94 | TAILQ_ENTRY(envsys_data) sensors_head; |
| 95 | uint32_t sensor; /* sensor number */ |
| 96 | uint32_t units; /* type of sensor */ |
| 97 | uint32_t state; /* sensor state */ |
| 98 | uint32_t flags; /* sensor flags */ |
| 99 | uint32_t rpms; /* for fans, nominal RPMs */ |
| 100 | int32_t rfact; /* for volts, factor x 10^4 */ |
| 101 | int32_t value_cur; /* current value */ |
| 102 | int32_t value_prev; /* previous value */ |
| 103 | int32_t value_max; /* max value */ |
| 104 | int32_t value_min; /* min value */ |
| 105 | int32_t private; /* private data for drivers */ |
| 106 | sysmon_envsys_lim_t limits; /* thresholds for monitoring */ |
| 107 | uint32_t upropset; /* userland property set? */ |
| 108 | krndsource_t rnd_src; /* source element for rnd(4) */ |
| 109 | char desc[ENVSYS_DESCLEN]; /* sensor description */ |
| 110 | }; |
| 111 | |
| 112 | typedef struct envsys_data envsys_data_t; |
| 113 | |
| 114 | /* sensor flags */ |
| 115 | #define ENVSYS_FPERCENT 0x00000001 /* sensor wants a percentage */ |
| 116 | #define ENVSYS_FVALID_MAX 0x00000002 /* max value is ok */ |
| 117 | #define ENVSYS_FVALID_MIN 0x00000004 /* min value is ok */ |
| 118 | #define ENVSYS_F_OBSOLETE 0x00000008 |
| 119 | #define ENVSYS_FCHANGERFACT 0x00000010 /* sensor can change rfact */ |
| 120 | |
| 121 | /* monitoring flags */ |
| 122 | #define ENVSYS_FMONCRITICAL 0x00000020 /* monitor a critical state */ |
| 123 | #define ENVSYS_FMONLIMITS 0x00000040 /* monitor limits/thresholds */ |
| 124 | #define ENVSYS_FMONSTCHANGED 0x00000400 /* monitor a battery/drive state */ |
| 125 | #define ENVSYS_FMONANY \ |
| 126 | (ENVSYS_FMONCRITICAL | ENVSYS_FMONLIMITS | ENVSYS_FMONSTCHANGED) |
| 127 | #define ENVSYS_FMONNOTSUPP 0x00000800 /* monitoring not supported */ |
| 128 | #define ENVSYS_FNEED_REFRESH 0x00001000 /* sensor needs refreshing */ |
| 129 | #define ENVSYS_FHAS_ENTROPY 0x00002000 /* sensor provides entropy |
| 130 | for rnd(4) */ |
| 131 | |
| 132 | /* |
| 133 | * Properties that can be set in upropset (and in the event_limit's |
| 134 | * flags field) |
| 135 | */ |
| 136 | #define PROP_CRITMAX 0x0001 |
| 137 | #define PROP_CRITMIN 0x0002 |
| 138 | #define PROP_WARNMAX 0x0004 |
| 139 | #define PROP_WARNMIN 0x0008 |
| 140 | #define PROP_BATTCAP 0x0010 |
| 141 | #define PROP_BATTWARN 0x0020 |
| 142 | #define PROP_BATTHIGH 0x0040 |
| 143 | #define PROP_BATTMAX 0x0080 |
| 144 | #define PROP_DESC 0x0100 |
| 145 | #define PROP_RFACT 0x0200 |
| 146 | |
| 147 | #define PROP_DRIVER_LIMITS 0x8000 |
| 148 | #define PROP_CAP_LIMITS (PROP_BATTCAP | PROP_BATTWARN | \ |
| 149 | PROP_BATTHIGH | PROP_BATTMAX) |
| 150 | #define PROP_VAL_LIMITS (PROP_CRITMAX | PROP_CRITMIN | \ |
| 151 | PROP_WARNMAX | PROP_WARNMIN) |
| 152 | #define PROP_LIMITS (PROP_CAP_LIMITS | PROP_VAL_LIMITS) |
| 153 | struct sme_event; |
| 154 | |
| 155 | struct sysmon_envsys { |
| 156 | const char *sme_name; /* envsys device name */ |
| 157 | u_int sme_nsensors; /* sensors count, from driver */ |
| 158 | u_int sme_fsensor; /* sensor index base, from sysmon */ |
| 159 | #define SME_SENSOR_IDX(sme, idx) ((idx) - (sme)->sme_fsensor) |
| 160 | int sme_class; /* class of device */ |
| 161 | #define SME_CLASS_BATTERY 1 /* device is a battery */ |
| 162 | #define SME_CLASS_ACADAPTER 2 /* device is an AC adapter */ |
| 163 | int sme_flags; /* additional flags */ |
| 164 | #define SME_FLAG_BUSY 0x00000001 /* device busy */ |
| 165 | #define SME_DISABLE_REFRESH 0x00000002 /* disable sme_refresh */ |
| 166 | #define SME_CALLOUT_INITIALIZED 0x00000004 /* callout was initialized */ |
| 167 | #define SME_INIT_REFRESH 0x00000008 /* call sme_refresh() after |
| 168 | interrupts are enabled in |
| 169 | the autoconf(9) process. */ |
| 170 | #define SME_POLL_ONLY 0x00000010 /* only poll sme_refresh */ |
| 171 | |
| 172 | void *sme_cookie; /* for ENVSYS back-end */ |
| 173 | |
| 174 | /* |
| 175 | * Function callback to receive data from device. |
| 176 | */ |
| 177 | void (*sme_refresh)(struct sysmon_envsys *, envsys_data_t *); |
| 178 | |
| 179 | /* |
| 180 | * Function callbacks to exchange limit/threshold values |
| 181 | * with device |
| 182 | */ |
| 183 | void (*sme_set_limits)(struct sysmon_envsys *, envsys_data_t *, |
| 184 | sysmon_envsys_lim_t *, uint32_t *); |
| 185 | void (*sme_get_limits)(struct sysmon_envsys *, envsys_data_t *, |
| 186 | sysmon_envsys_lim_t *, uint32_t *); |
| 187 | |
| 188 | struct workqueue *sme_wq; /* the workqueue for the events */ |
| 189 | struct callout sme_callout; /* for the events */ |
| 190 | uint64_t sme_events_timeout; /* the timeout used in the callout */ |
| 191 | |
| 192 | /* |
| 193 | * linked list for the sysmon envsys devices. |
| 194 | */ |
| 195 | LIST_ENTRY(sysmon_envsys) sme_list; |
| 196 | |
| 197 | /* |
| 198 | * linked list for the events that a device maintains. |
| 199 | */ |
| 200 | LIST_HEAD(, sme_event) sme_events_list; |
| 201 | |
| 202 | /* |
| 203 | * tailq for the sensors that a device maintains. |
| 204 | */ |
| 205 | TAILQ_HEAD(, envsys_data) sme_sensors_list; |
| 206 | |
| 207 | /* |
| 208 | * Locking/synchronization. |
| 209 | */ |
| 210 | int sme_busy; /* number of items on workqueue, |
| 211 | sme_mtx or sme_work_mtx to read, |
| 212 | both to write */ |
| 213 | kmutex_t sme_mtx; |
| 214 | kmutex_t sme_work_mtx; |
| 215 | kcondvar_t sme_condvar; |
| 216 | }; |
| 217 | |
| 218 | int sysmonopen_envsys(dev_t, int, int, struct lwp *); |
| 219 | int sysmonclose_envsys(dev_t, int, int, struct lwp *); |
| 220 | int sysmonioctl_envsys(dev_t, u_long, void *, int, struct lwp *); |
| 221 | |
| 222 | struct sysmon_envsys *sysmon_envsys_create(void); |
| 223 | void sysmon_envsys_destroy(struct sysmon_envsys *); |
| 224 | |
| 225 | int sysmon_envsys_register(struct sysmon_envsys *); |
| 226 | void sysmon_envsys_unregister(struct sysmon_envsys *); |
| 227 | |
| 228 | int sysmon_envsys_sensor_attach(struct sysmon_envsys *, envsys_data_t *); |
| 229 | int sysmon_envsys_sensor_detach(struct sysmon_envsys *, envsys_data_t *); |
| 230 | |
| 231 | uint32_t sysmon_envsys_get_max_value(bool (*)(const envsys_data_t*), bool); |
| 232 | |
| 233 | void sysmon_envsys_sensor_event(struct sysmon_envsys *, envsys_data_t *, |
| 234 | int); |
| 235 | |
| 236 | void sysmon_envsys_refresh_sensor(struct sysmon_envsys *, envsys_data_t *); |
| 237 | |
| 238 | typedef bool (*sysmon_envsys_callback_t)(const struct sysmon_envsys *, |
| 239 | const envsys_data_t *, void*); |
| 240 | |
| 241 | void sysmon_envsys_foreach_sensor(sysmon_envsys_callback_t, void *, bool); |
| 242 | |
| 243 | int sysmon_envsys_update_limits(struct sysmon_envsys *, envsys_data_t *); |
| 244 | |
| 245 | int sysmon_envsys_init(void); |
| 246 | int sysmon_envsys_fini(void); |
| 247 | |
| 248 | /***************************************************************************** |
| 249 | * Watchdog timer support |
| 250 | *****************************************************************************/ |
| 251 | |
| 252 | struct sysmon_wdog { |
| 253 | const char *smw_name; /* watchdog device name */ |
| 254 | |
| 255 | LIST_ENTRY(sysmon_wdog) smw_list; |
| 256 | |
| 257 | void *smw_cookie; /* for watchdog back-end */ |
| 258 | int (*smw_setmode)(struct sysmon_wdog *); |
| 259 | int (*smw_tickle)(struct sysmon_wdog *); |
| 260 | u_int smw_period; /* timer period (in seconds) */ |
| 261 | int smw_mode; /* timer mode */ |
| 262 | u_int smw_refcnt; /* references */ |
| 263 | pid_t smw_tickler; /* last process to tickle */ |
| 264 | }; |
| 265 | |
| 266 | int sysmonopen_wdog(dev_t, int, int, struct lwp *); |
| 267 | int sysmonclose_wdog(dev_t, int, int, struct lwp *); |
| 268 | int sysmonioctl_wdog(dev_t, u_long, void *, int, struct lwp *); |
| 269 | |
| 270 | int sysmon_wdog_setmode(struct sysmon_wdog *, int, u_int); |
| 271 | int sysmon_wdog_register(struct sysmon_wdog *); |
| 272 | int sysmon_wdog_unregister(struct sysmon_wdog *); |
| 273 | |
| 274 | int sysmon_wdog_init(void); |
| 275 | int sysmon_wdog_fini(void); |
| 276 | |
| 277 | /***************************************************************************** |
| 278 | * Power management support |
| 279 | *****************************************************************************/ |
| 280 | |
| 281 | struct sysmon_pswitch { |
| 282 | const char *smpsw_name; /* power switch name */ |
| 283 | int smpsw_type; /* power switch type */ |
| 284 | |
| 285 | LIST_ENTRY(sysmon_pswitch) smpsw_list; |
| 286 | }; |
| 287 | |
| 288 | int sysmonopen_power(dev_t, int, int, struct lwp *); |
| 289 | int sysmonclose_power(dev_t, int, int, struct lwp *); |
| 290 | int sysmonread_power(dev_t, struct uio *, int); |
| 291 | int sysmonpoll_power(dev_t, int, struct lwp *); |
| 292 | int sysmonkqfilter_power(dev_t, struct knote *); |
| 293 | int sysmonioctl_power(dev_t, u_long, void *, int, struct lwp *); |
| 294 | |
| 295 | void sysmon_power_settype(const char *); |
| 296 | |
| 297 | int sysmon_pswitch_register(struct sysmon_pswitch *); |
| 298 | void sysmon_pswitch_unregister(struct sysmon_pswitch *); |
| 299 | |
| 300 | void sysmon_pswitch_event(struct sysmon_pswitch *, int); |
| 301 | void sysmon_penvsys_event(struct penvsys_state *, int); |
| 302 | |
| 303 | int sysmon_power_init(void); |
| 304 | int sysmon_power_fini(void); |
| 305 | |
| 306 | /* |
| 307 | * Interface to sysmon common code used for autoloading |
| 308 | */ |
| 309 | struct sysmon_opvec { |
| 310 | int (*so_open)(dev_t, int, int, struct lwp*); |
| 311 | int (*so_close)(dev_t, int, int, struct lwp*); |
| 312 | int (*so_ioctl)(dev_t, u_long, void *, int, struct lwp*); |
| 313 | int (*so_read)(dev_t, struct uio*, int); |
| 314 | int (*so_poll)(dev_t, int, struct lwp*); |
| 315 | int (*so_filter)(dev_t, struct knote*); |
| 316 | }; |
| 317 | |
| 318 | int sysmon_init(void); |
| 319 | int sysmon_fini(void); |
| 320 | int sysmon_attach_minor(int, struct sysmon_opvec*); |
| 321 | |
| 322 | #endif /* _DEV_SYSMON_SYSMONVAR_H_ */ |
| 323 | |