Module Name:    src
Committed By:   pgoyette
Date:           Sun Jun 19 03:12:31 UTC 2011

Modified Files:
        src/share/man/man4: swsensor.4
        src/sys/dev/sysmon: swsensor.c

Log Message:
Rather than requiring the user to know the internal encoding of sensor
types, allow the user to specify the type using the units description.

XXX Numeric specification is still permitted but will be removed soon.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/share/man/man4/swsensor.4
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/sysmon/swsensor.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man4/swsensor.4
diff -u src/share/man/man4/swsensor.4:1.8 src/share/man/man4/swsensor.4:1.9
--- src/share/man/man4/swsensor.4:1.8	Tue Jun  7 07:27:31 2011
+++ src/share/man/man4/swsensor.4	Sun Jun 19 03:12:31 2011
@@ -1,4 +1,4 @@
-.\"	$NetBSD: swsensor.4,v 1.8 2011/06/07 07:27:31 wiz Exp $
+.\"	$NetBSD: swsensor.4,v 1.9 2011/06/19 03:12:31 pgoyette Exp $
 .\"
 .\" Copyright (c) 2010 The NetBSD Foundation
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 4, 2011
+.Dd June 19, 2011
 .Dt SWSENSOR 4
 .Os
 .Sh NAME
@@ -49,13 +49,13 @@
 By default, the sensor is of type
 .Dv ENVSYS_UNITS_INTEGER .
 .Pp
-The following integer values can be specified in the
+The following values can be specified in the
 .Xr modload 8
 command when loading the
 .Nm
 module to alter the driver's behavior.
 .Pp
-.Bl -tag -width "variable"
+.Bl -tag -width "percentage"
 .It Sy "Variable" Sy "Usage"
 .It Li "mode"
 Controls whether or not
@@ -72,7 +72,7 @@
 comparison between the sensor's limit and its current value
 .El
 .It Li "limit"
-The initial limit value, if limit emulation is selected (ie, if
+The initial alarm limit value, if limit emulation is selected (ie, if
 .Dv mode
 is set to 1 or 2)
 .It Li "value_max"
@@ -88,16 +88,26 @@
 .Dv ENVSYS_FPERCENT
 flag.
 .It Li "type"
-Override the sensor's unit/type.
+Define the sensor's unit/type.
+By default, a Temperature sensor is created.
+Any of the string values from the following table can be specified:
+.Bl -column "Battery capacity" "Battery charge" "Ampere hour"
+.It "Temperature"      Ta "Fan"       Ta "Voltage AC"
+.It "Voltage DC"       Ta "Ohms"      Ta "Watts"
+.It "Ampere"           Ta "Watt hour" Ta "Ampere hour"
+.It "Indicator"        Ta "Integer"   Ta "Drive"
+.It "Battery capacity" Ta "Battery charge"
+.El
+(Values are case-sensitive, and spaces must be included.)
 .It Li "value"
 Provide an initial value for the sensor.
 If this is omitted, the sensor's initial value is set to zero.
 .El
 .Pp
 For example,
-.Dl Ic modload -i type=1 swsensor
+.Dl Ic modload -s type=Voltage\e DC swsensor
 will create a sensor of type
-.Dv ENVSYS_UNITS_SFANRPM ,
+.Dv ENVSYS_UNITS_SVOLTS_DC ,
 while
 .Dl Ic modload -i mode=1 -i limit=50 swsensor
 will create a sensor which has an initial, device-provided limit of 50.

Index: src/sys/dev/sysmon/swsensor.c
diff -u src/sys/dev/sysmon/swsensor.c:1.9 src/sys/dev/sysmon/swsensor.c:1.10
--- src/sys/dev/sysmon/swsensor.c:1.9	Sat Jun  4 13:26:51 2011
+++ src/sys/dev/sysmon/swsensor.c	Sun Jun 19 03:12:31 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: swsensor.c,v 1.9 2011/06/04 13:26:51 pgoyette Exp $ */
+/*	$NetBSD: swsensor.c,v 1.10 2011/06/19 03:12:31 pgoyette Exp $ */
 /*
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: swsensor.c,v 1.9 2011/06/04 13:26:51 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: swsensor.c,v 1.10 2011/06/19 03:12:31 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -35,6 +35,7 @@
 #include <sys/sysctl.h>
 
 #include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmon_envsysvar.h>
 
 #include <prop/proplib.h>
 
@@ -159,8 +160,12 @@
 swsensor_init(void *arg)
 {
 	int error;
+	const char *key, *str;
 	prop_dictionary_t pd = (prop_dictionary_t)arg;
-	prop_object_t po = NULL;
+	prop_object_t po, obj;
+	prop_object_iterator_t iter;
+	prop_type_t type;
+	const struct sme_descr_entry *descr;
 
 	swsensor_sme = sysmon_envsys_create();
 	if (swsensor_sme == NULL)
@@ -172,116 +177,163 @@
 	swsensor_sme->sme_set_limits = NULL;
 	swsensor_sme->sme_get_limits = NULL;
 
-	/* See if prop dictionary supplies a sensor type */
-	if (pd != NULL)
-		po = prop_dictionary_get(pd, "type");
+	/* Set defaults in case no prop dictionary given */
 
-	if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
-		swsensor_edata.units = prop_number_integer_value(po);
-	else
-		swsensor_edata.units = ENVSYS_INTEGER;
+	swsensor_edata.units = ENVSYS_INTEGER;
+	swsensor_edata.flags = 0;
+	sw_sensor_mode = 0;
+	sw_sensor_value = 0;
+	sw_sensor_limit = 0;
 
-	/* See if prop dictionary supplies sensor flags */
-	if (pd != NULL)
-		po = prop_dictionary_get(pd, "flags");
+	/* Iterate over the provided dictionary, if any */
+	if (pd != NULL) {
+		iter = prop_dictionary_iterator(pd);
+		if (iter == NULL)
+			return ENOMEM;
+
+		while ((obj = prop_object_iterator_next(iter)) != NULL) {
+			key = prop_dictionary_keysym_cstring_nocopy(obj);
+			po  = prop_dictionary_get_keysym(pd, obj);
+			type = prop_object_type(po);
+
+			/* Sensor type/units */
+			if (strcmp(key, "type") == 0) {
+				if (type == PROP_TYPE_NUMBER) {
+					swsensor_edata.units =
+					    prop_number_integer_value(po);
+					continue;
+				}
+				if (type != PROP_TYPE_STRING)
+					return EINVAL;
+				str = prop_dictionary_keysym_cstring_nocopy(po);
+				descr = sme_find_table_desc(SME_DESC_UNITS,
+							    str);
+				if (descr->type < 0)
+					return EINVAL;
+				swsensor_edata.units = descr->type;
+				continue;
+			}
+
+			/* Sensor flags */
+			if (strcmp(key, "flags") == 0) {
+				if (type != PROP_TYPE_NUMBER)
+					return EINVAL;
+				swsensor_edata.flags =
+				    prop_number_integer_value(po);
+				continue;
+			}
+
+			/* Sensor limit behavior
+			 *	0 - simple sensor, no hw limits
+			 *	1 - simple sensor, hw provides initial limit
+			 *	2 - complex sensor, hw provides settable 
+			 *	    limits and does its own limit checking
+			 */
+			if (strcmp(key, "mode") == 0) {
+				if (type != PROP_TYPE_NUMBER)
+					return EINVAL;
+				sw_sensor_mode = prop_number_integer_value(po);
+				if (sw_sensor_mode > 2)
+					sw_sensor_mode = 2;
+				else if (sw_sensor_mode < 0)
+					sw_sensor_mode = 0;
+				continue;
+			}
+
+			/* Grab any limit that might be specified */
+			if (strcmp(key, "limit") == 0) {
+				if (type != PROP_TYPE_NUMBER)
+					return EINVAL;
+				sw_sensor_limit = prop_number_integer_value(po);
+				continue;
+			}
+
+			/* Grab the initial value */
+			if (strcmp(key, "value") == 0) {
+				if (type != PROP_TYPE_NUMBER)
+					return EINVAL;
+				sw_sensor_value = prop_number_integer_value(po);
+				continue;
+			}
+
+			/* Grab value_min and value_max */
+			if (strcmp(key, "value_min") == 0) {
+				if (type != PROP_TYPE_NUMBER)
+					return EINVAL;
+				swsensor_edata.value_min =
+				    prop_number_integer_value(po);
+				swsensor_edata.flags |= ENVSYS_FVALID_MIN;
+				continue;
+			}
+			if (strcmp(key, "value_max") == 0) {
+				if (type != PROP_TYPE_NUMBER)
+					return EINVAL;
+				swsensor_edata.value_max =
+				    prop_number_integer_value(po);
+				swsensor_edata.flags |= ENVSYS_FVALID_MAX;
+				continue;
+			}
+
+			/* See if sensor reports percentages vs raw values */
+			if (strcmp(key, "percentage") == 0) {
+				if (type != PROP_TYPE_BOOL)
+					return EINVAL;
+				if (prop_bool_true(po))
+					swsensor_edata.flags |= ENVSYS_FPERCENT;
+				continue;
+			}
 
-	if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
-		swsensor_edata.flags = prop_number_integer_value(po);
-	else
-		swsensor_edata.flags = 0;
+			/* Unrecognized dicttionary object */
+			return EINVAL;
 
-	/*
-	 * Get requested sensor limit behavior
-	 *	0 - simple sensor, no hw limits
-	 *	1 - simple sensor, hw provides an initial limit
-	 *	2 - complex sensor, hw provides settable limits and
-	 *	    does its own limit checking
-	 */
-	if (pd != NULL)
-		po = prop_dictionary_get(pd, "mode");
-
-	if  (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER) {
-		sw_sensor_mode = prop_number_integer_value(po);
-		if (sw_sensor_mode > 2)
-			sw_sensor_mode = 2;
-	} else
-		sw_sensor_mode = 0;
+		} /* while */
+		prop_object_iterator_release(iter);
+	}
 
+	/* Initialize limit processing */
 	if (sw_sensor_mode >= 1)
 		swsensor_sme->sme_get_limits = swsensor_get_limits;
 
 	if (sw_sensor_mode == 2)
 		swsensor_sme->sme_set_limits = swsensor_set_limits;
 
-	/* See if a limit value was provided - if not, use 0 */
 	if (sw_sensor_mode != 0) {
 		swsensor_edata.flags |= ENVSYS_FMONLIMITS;
-		sw_sensor_limit = 0;
-		if (pd != NULL)
-			po = prop_dictionary_get(pd, "limit");
-
-		if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
-			sw_sensor_limit = prop_number_integer_value(po);
-
 		swsensor_get_limits(swsensor_sme, &swsensor_edata,
 		    &sw_sensor_deflims, &sw_sensor_defprops);
 	}
 
-	/* See if an initial value was specified */
-	if (pd != NULL)
-		po = prop_dictionary_get(pd, "value");
-
-	if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
-		sw_sensor_value = prop_number_integer_value(po);
-
-	/* Retrieve any value_{max,min} that might be present */
-	if (pd != NULL) {
-		po = prop_dictionary_get(pd, "value_max");
-		if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER) {
-			swsensor_edata.value_max =
-			    prop_number_integer_value(po);
-			swsensor_edata.flags |= ENVSYS_FVALID_MAX;
-		}
-
-		po = prop_dictionary_get(pd, "value_min");
-		if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER) {
-			swsensor_edata.value_min =
-			    prop_number_integer_value(po);
-			swsensor_edata.flags |= ENVSYS_FVALID_MIN;
-		}
-	}
-
-	/* See if this sensor should report percentages vs raw values */
-	if (pd != NULL) {
-		po = prop_dictionary_get(pd, "percentage");
-		if (po != NULL &&
-		    prop_object_type(po) == PROP_TYPE_BOOL &&
-		    prop_bool_true(po))
-			swsensor_edata.flags |= ENVSYS_FPERCENT;
-	}
-
-	swsensor_edata.state = ENVSYS_SVALID;
-	swsensor_edata.value_cur = 0;
+	/*
+	 * If {min, max} value range was specified, make sure that the
+	 * current value is within the range.
+	 */
+	if (swsensor_edata.flags & ENVSYS_FVALID_MAX &&
+	    sw_sensor_value > swsensor_edata.value_max)
+		swsensor_edata.state = ENVSYS_SINVALID;
+	if (swsensor_edata.flags & ENVSYS_FVALID_MIN &&
+	    sw_sensor_value < swsensor_edata.value_min)
+		swsensor_edata.state = ENVSYS_SINVALID;
+	else
+		swsensor_edata.state = ENVSYS_SVALID;
+	swsensor_edata.value_cur = sw_sensor_value;
 
 	strlcpy(swsensor_edata.desc, "sensor", ENVSYS_DESCLEN);
 
 	error = sysmon_envsys_sensor_attach(swsensor_sme, &swsensor_edata);
-
-	if (error == 0)
-		error = sysmon_envsys_register(swsensor_sme);
-	else {
+	if (error != 0) {
 		aprint_error("sysmon_envsys_sensor_attach failed: %d\n", error);
 		return error;
 	}
 
-	if (error == 0)
-		sysctl_swsensor_setup();
-	else
+	error = sysmon_envsys_register(swsensor_sme);
+	if (error != 0)
 		aprint_error("sysmon_envsys_register failed: %d\n", error);
+		return error;
+
+	sysctl_swsensor_setup();
+	aprint_normal("swsensor: initialized\n");
 
-	if (error == 0)
-		aprint_normal("swsensor: initialized\n");
-	return error;
+	return 0;
 }
 
 static

Reply via email to