Sun Jun 19 15:52:48 2011 UTC ()
Use {...} to prevent premature exit from initialization function - this
lets the atf tests run again.

Move validation of current value vs min/max into the refresh routine
where it will get checked every time, not just at initialization.

While here, do a little more housekeeping:
  - Retrieve numeric property value once
  - Ensure that a numeric-specified sensor type is valid
  - printout any unrecognized properties (DEBUG only)


(pgoyette)
diff -r1.11 -r1.12 src/sys/dev/sysmon/swsensor.c

cvs diff -r1.11 -r1.12 src/sys/dev/sysmon/swsensor.c (expand / switch to unified diff)

--- src/sys/dev/sysmon/swsensor.c 2011/06/19 04:08:48 1.11
+++ src/sys/dev/sysmon/swsensor.c 2011/06/19 15:52:48 1.12
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: swsensor.c,v 1.11 2011/06/19 04:08:48 pgoyette Exp $ */ 1/* $NetBSD: swsensor.c,v 1.12 2011/06/19 15:52:48 pgoyette Exp $ */
2/* 2/*
3 * Copyright (c) 2008 The NetBSD Foundation, Inc. 3 * Copyright (c) 2008 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: swsensor.c,v 1.11 2011/06/19 04:08:48 pgoyette Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: swsensor.c,v 1.12 2011/06/19 15:52:48 pgoyette Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/kernel.h> 33#include <sys/kernel.h>
34#include <sys/module.h> 34#include <sys/module.h>
35#include <sys/sysctl.h> 35#include <sys/sysctl.h>
36 36
37#include <dev/sysmon/sysmonvar.h> 37#include <dev/sysmon/sysmonvar.h>
38#include <dev/sysmon/sysmon_envsysvar.h> 38#include <dev/sysmon/sysmon_envsysvar.h>
39 39
40#include <prop/proplib.h> 40#include <prop/proplib.h>
41 41
42#ifndef _MODULE 42#ifndef _MODULE
43#include "opt_modular.h" 43#include "opt_modular.h"
@@ -93,26 +93,35 @@ sysctl_swsensor_setup(void) @@ -93,26 +93,35 @@ sysctl_swsensor_setup(void)
93 sensor_value_sysctl = me->sysctl_num; 93 sensor_value_sysctl = me->sysctl_num;
94} 94}
95 95
96/* 96/*
97 * "Polling" routine to update sensor value 97 * "Polling" routine to update sensor value
98 */ 98 */
99static 99static
100void 100void
101swsensor_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 101swsensor_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
102{ 102{
103 103
104 edata->value_cur = sw_sensor_value; 104 edata->value_cur = sw_sensor_value;
105 105
 106 /* If value outside of legal range, mark it invalid */
 107 if ((edata->flags & ENVSYS_FVALID_MIN &&
 108 edata->value_cur < edata->value_min) ||
 109 (edata->flags & ENVSYS_FVALID_MAX &&
 110 edata->value_cur > edata->value_max)) {
 111 edata->state = ENVSYS_SINVALID;
 112 return;
 113 }
 114
106 /* 115 /*
107 * Set state. If we're handling the limits ourselves, do the 116 * Set state. If we're handling the limits ourselves, do the
108 * compare; otherwise just assume the value is valid. 117 * compare; otherwise just assume the value is valid.
109 */ 118 */
110 if ((sw_sensor_mode == 2) && (edata->upropset & PROP_CRITMIN) && 119 if ((sw_sensor_mode == 2) && (edata->upropset & PROP_CRITMIN) &&
111 (edata->upropset & PROP_DRIVER_LIMITS) && 120 (edata->upropset & PROP_DRIVER_LIMITS) &&
112 (edata->value_cur < edata->limits.sel_critmin)) 121 (edata->value_cur < edata->limits.sel_critmin))
113 edata->state = ENVSYS_SCRITUNDER; 122 edata->state = ENVSYS_SCRITUNDER;
114 else 123 else
115 edata->state = ENVSYS_SVALID; 124 edata->state = ENVSYS_SVALID;
116} 125}
117 126
118/* 127/*
@@ -149,27 +158,27 @@ swsensor_set_limits(struct sysmon_envsys @@ -149,27 +158,27 @@ swsensor_set_limits(struct sysmon_envsys
149 *props |= PROP_DRIVER_LIMITS; 158 *props |= PROP_DRIVER_LIMITS;
150 else 159 else
151 *props &= ~PROP_DRIVER_LIMITS; 160 *props &= ~PROP_DRIVER_LIMITS;
152} 161}
153 162
154/* 163/*
155 * Module management 164 * Module management
156 */ 165 */
157 166
158static 167static
159int 168int
160swsensor_init(void *arg) 169swsensor_init(void *arg)
161{ 170{
162 int error; 171 int error, val = 0;
163 const char *key, *str; 172 const char *key, *str;
164 prop_dictionary_t pd = (prop_dictionary_t)arg; 173 prop_dictionary_t pd = (prop_dictionary_t)arg;
165 prop_object_t po, obj; 174 prop_object_t po, obj;
166 prop_object_iterator_t iter; 175 prop_object_iterator_t iter;
167 prop_type_t type; 176 prop_type_t type;
168 const struct sme_descr_entry *descr; 177 const struct sme_descr_entry *descr;
169 178
170 swsensor_sme = sysmon_envsys_create(); 179 swsensor_sme = sysmon_envsys_create();
171 if (swsensor_sme == NULL) 180 if (swsensor_sme == NULL)
172 return ENOTTY; 181 return ENOTTY;
173 182
174 swsensor_sme->sme_name = "swsensor"; 183 swsensor_sme->sme_name = "swsensor";
175 swsensor_sme->sme_cookie = &swsensor_edata; 184 swsensor_sme->sme_cookie = &swsensor_edata;
@@ -185,160 +194,155 @@ swsensor_init(void *arg) @@ -185,160 +194,155 @@ swsensor_init(void *arg)
185 sw_sensor_value = 0; 194 sw_sensor_value = 0;
186 sw_sensor_limit = 0; 195 sw_sensor_limit = 0;
187 196
188 /* Iterate over the provided dictionary, if any */ 197 /* Iterate over the provided dictionary, if any */
189 if (pd != NULL) { 198 if (pd != NULL) {
190 iter = prop_dictionary_iterator(pd); 199 iter = prop_dictionary_iterator(pd);
191 if (iter == NULL) 200 if (iter == NULL)
192 return ENOMEM; 201 return ENOMEM;
193 202
194 while ((obj = prop_object_iterator_next(iter)) != NULL) { 203 while ((obj = prop_object_iterator_next(iter)) != NULL) {
195 key = prop_dictionary_keysym_cstring_nocopy(obj); 204 key = prop_dictionary_keysym_cstring_nocopy(obj);
196 po = prop_dictionary_get_keysym(pd, obj); 205 po = prop_dictionary_get_keysym(pd, obj);
197 type = prop_object_type(po); 206 type = prop_object_type(po);
 207 if (type == PROP_TYPE_NUMBER)
 208 val = prop_number_integer_value(po);
198 209
199 /* Sensor type/units */ 210 /* Sensor type/units */
200 if (strcmp(key, "type") == 0) { 211 if (strcmp(key, "type") == 0) {
201 if (type == PROP_TYPE_NUMBER) { 212 if (type == PROP_TYPE_NUMBER) {
202 swsensor_edata.units = 213 descr = sme_find_table_entry(
203 prop_number_integer_value(po); 214 SME_DESC_UNITS, val);
 215 if (descr == NULL)
 216 return EINVAL;
 217 swsensor_edata.units = descr->type;
204 continue; 218 continue;
205 } 219 }
206 if (type != PROP_TYPE_STRING) 220 if (type != PROP_TYPE_STRING)
207 return EINVAL; 221 return EINVAL;
208 str = prop_string_cstring_nocopy(po); 222 str = prop_string_cstring_nocopy(po);
209 descr = sme_find_table_desc(SME_DESC_UNITS, 223 descr = sme_find_table_desc(SME_DESC_UNITS,
210 str); 224 str);
211 if (descr->type < 0) 225 if (descr == NULL)
212 return EINVAL; 226 return EINVAL;
213 swsensor_edata.units = descr->type; 227 swsensor_edata.units = descr->type;
214 continue; 228 continue;
215 } 229 }
216 230
217 /* Sensor flags */ 231 /* Sensor flags */
218 if (strcmp(key, "flags") == 0) { 232 if (strcmp(key, "flags") == 0) {
219 if (type != PROP_TYPE_NUMBER) 233 if (type != PROP_TYPE_NUMBER)
220 return EINVAL; 234 return EINVAL;
221 swsensor_edata.flags = 235 swsensor_edata.flags = val;
222 prop_number_integer_value(po); 
223 continue; 236 continue;
224 } 237 }
225 238
226 /* Sensor limit behavior 239 /* Sensor limit behavior
227 * 0 - simple sensor, no hw limits 240 * 0 - simple sensor, no hw limits
228 * 1 - simple sensor, hw provides initial limit 241 * 1 - simple sensor, hw provides initial limit
229 * 2 - complex sensor, hw provides settable  242 * 2 - complex sensor, hw provides settable
230 * limits and does its own limit checking 243 * limits and does its own limit checking
231 */ 244 */
232 if (strcmp(key, "mode") == 0) { 245 if (strcmp(key, "mode") == 0) {
233 if (type != PROP_TYPE_NUMBER) 246 if (type != PROP_TYPE_NUMBER)
234 return EINVAL; 247 return EINVAL;
235 sw_sensor_mode = prop_number_integer_value(po); 248 sw_sensor_mode = val;
236 if (sw_sensor_mode > 2) 249 if (sw_sensor_mode > 2)
237 sw_sensor_mode = 2; 250 sw_sensor_mode = 2;
238 else if (sw_sensor_mode < 0) 251 else if (sw_sensor_mode < 0)
239 sw_sensor_mode = 0; 252 sw_sensor_mode = 0;
240 continue; 253 continue;
241 } 254 }
242 255
243 /* Grab any limit that might be specified */ 256 /* Grab any limit that might be specified */
244 if (strcmp(key, "limit") == 0) { 257 if (strcmp(key, "limit") == 0) {
245 if (type != PROP_TYPE_NUMBER) 258 if (type != PROP_TYPE_NUMBER)
246 return EINVAL; 259 return EINVAL;
247 sw_sensor_limit = prop_number_integer_value(po); 260 sw_sensor_limit = val;
248 continue; 261 continue;
249 } 262 }
250 263
251 /* Grab the initial value */ 264 /* Grab the initial value */
252 if (strcmp(key, "value") == 0) { 265 if (strcmp(key, "value") == 0) {
253 if (type != PROP_TYPE_NUMBER) 266 if (type != PROP_TYPE_NUMBER)
254 return EINVAL; 267 return EINVAL;
255 sw_sensor_value = prop_number_integer_value(po); 268 sw_sensor_value = val;
256 continue; 269 continue;
257 } 270 }
258 271
259 /* Grab value_min and value_max */ 272 /* Grab value_min and value_max */
260 if (strcmp(key, "value_min") == 0) { 273 if (strcmp(key, "value_min") == 0) {
261 if (type != PROP_TYPE_NUMBER) 274 if (type != PROP_TYPE_NUMBER)
262 return EINVAL; 275 return EINVAL;
263 swsensor_edata.value_min = 276 swsensor_edata.value_min = val;
264 prop_number_integer_value(po); 
265 swsensor_edata.flags |= ENVSYS_FVALID_MIN; 277 swsensor_edata.flags |= ENVSYS_FVALID_MIN;
266 continue; 278 continue;
267 } 279 }
268 if (strcmp(key, "value_max") == 0) { 280 if (strcmp(key, "value_max") == 0) {
269 if (type != PROP_TYPE_NUMBER) 281 if (type != PROP_TYPE_NUMBER)
270 return EINVAL; 282 return EINVAL;
271 swsensor_edata.value_max = 283 swsensor_edata.value_max = val;
272 prop_number_integer_value(po); 
273 swsensor_edata.flags |= ENVSYS_FVALID_MAX; 284 swsensor_edata.flags |= ENVSYS_FVALID_MAX;
274 continue; 285 continue;
275 } 286 }
276 287
277 /* See if sensor reports percentages vs raw values */ 288 /* See if sensor reports percentages vs raw values */
278 if (strcmp(key, "percentage") == 0) { 289 if (strcmp(key, "percentage") == 0) {
279 if (type != PROP_TYPE_BOOL) 290 if (type != PROP_TYPE_BOOL)
280 return EINVAL; 291 return EINVAL;
281 if (prop_bool_true(po)) 292 if (prop_bool_true(po))
282 swsensor_edata.flags |= ENVSYS_FPERCENT; 293 swsensor_edata.flags |= ENVSYS_FPERCENT;
283 continue; 294 continue;
284 } 295 }
285 296
286 /* Unrecognized dicttionary object */ 297 /* Unrecognized dicttionary object */
 298#ifdef DEBUG
 299 printf("%s: unknown attribute %s\n", __func__, key);
 300#endif
287 return EINVAL; 301 return EINVAL;
288 302
289 } /* while */ 303 } /* while */
290 prop_object_iterator_release(iter); 304 prop_object_iterator_release(iter);
291 } 305 }
292 306
293 /* Initialize limit processing */ 307 /* Initialize limit processing */
294 if (sw_sensor_mode >= 1) 308 if (sw_sensor_mode >= 1)
295 swsensor_sme->sme_get_limits = swsensor_get_limits; 309 swsensor_sme->sme_get_limits = swsensor_get_limits;
296 310
297 if (sw_sensor_mode == 2) 311 if (sw_sensor_mode == 2)
298 swsensor_sme->sme_set_limits = swsensor_set_limits; 312 swsensor_sme->sme_set_limits = swsensor_set_limits;
299 313
300 if (sw_sensor_mode != 0) { 314 if (sw_sensor_mode != 0) {
301 swsensor_edata.flags |= ENVSYS_FMONLIMITS; 315 swsensor_edata.flags |= ENVSYS_FMONLIMITS;
302 swsensor_get_limits(swsensor_sme, &swsensor_edata, 316 swsensor_get_limits(swsensor_sme, &swsensor_edata,
303 &sw_sensor_deflims, &sw_sensor_defprops); 317 &sw_sensor_deflims, &sw_sensor_defprops);
304 } 318 }
305 319
306 /* 
307 * If {min, max} value range was specified, make sure that the 
308 * current value is within the range. 
309 */ 
310 if (swsensor_edata.flags & ENVSYS_FVALID_MAX && 
311 sw_sensor_value > swsensor_edata.value_max) 
312 swsensor_edata.state = ENVSYS_SINVALID; 
313 if (swsensor_edata.flags & ENVSYS_FVALID_MIN && 
314 sw_sensor_value < swsensor_edata.value_min) 
315 swsensor_edata.state = ENVSYS_SINVALID; 
316 else 
317 swsensor_edata.state = ENVSYS_SVALID; 
318 swsensor_edata.value_cur = sw_sensor_value; 
319 
320 strlcpy(swsensor_edata.desc, "sensor", ENVSYS_DESCLEN); 320 strlcpy(swsensor_edata.desc, "sensor", ENVSYS_DESCLEN);
321 321
 322 /* Wait for refresh to validate the sensor value */
 323 swsensor_edata.state = ENVSYS_SINVALID;
 324
322 error = sysmon_envsys_sensor_attach(swsensor_sme, &swsensor_edata); 325 error = sysmon_envsys_sensor_attach(swsensor_sme, &swsensor_edata);
323 if (error != 0) { 326 if (error != 0) {
324 aprint_error("sysmon_envsys_sensor_attach failed: %d\n", error); 327 aprint_error("sysmon_envsys_sensor_attach failed: %d\n", error);
325 return error; 328 return error;
326 } 329 }
327 330
328 error = sysmon_envsys_register(swsensor_sme); 331 error = sysmon_envsys_register(swsensor_sme);
329 if (error != 0) 332 if (error != 0) {
330 aprint_error("sysmon_envsys_register failed: %d\n", error); 333 aprint_error("sysmon_envsys_register failed: %d\n", error);
331 return error; 334 return error;
 335 }
332 336
333 sysctl_swsensor_setup(); 337 sysctl_swsensor_setup();
334 aprint_normal("swsensor: initialized\n"); 338 aprint_normal("swsensor: initialized\n");
335 339
336 return 0; 340 return 0;
337} 341}
338 342
339static 343static
340int 344int
341swsensor_fini(void *arg) 345swsensor_fini(void *arg)
342{ 346{
343 347
344 sysmon_envsys_unregister(swsensor_sme); 348 sysmon_envsys_unregister(swsensor_sme);