Module Name:    src
Committed By:   pgoyette
Date:           Sat Dec 11 04:13:03 UTC 2010

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

Log Message:
Enhance the swsensor(4) pseudo-device's capabilities to emulate more
sensor types


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/share/man/man4/swsensor.4
cvs rdiff -u -r1.4 -r1.5 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.2 src/share/man/man4/swsensor.4:1.3
--- src/share/man/man4/swsensor.4:1.2	Tue Oct 19 12:53:23 2010
+++ src/share/man/man4/swsensor.4	Sat Dec 11 04:13:03 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: swsensor.4,v 1.2 2010/10/19 12:53:23 wiz Exp $
+.\"	$NetBSD: swsensor.4,v 1.3 2010/12/11 04:13:03 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 October 19, 2010
+.Dd December 9, 2010
 .Dt SWSENSOR 4
 .Os
 .Sh NAME
@@ -42,17 +42,50 @@
 .Xr  sysctl 8
 and
 .Xr envstat 8 .
-The driver creates a single sensor which is intended to be loaded as a
-kernel module.
+The driver is intended to be loaded as a kernel module.
+One can, however, include the
+.Nm
+driver directly in a kernel using the configuration from the synopsis.
 By default, the sensor is of type
 .Dv ENVSYS_UNITS_INTEGER .
-This can be overridden when the module is loaded by passing the desired
-sensor type in the property list with
-.Xr modload 8 .
+.Pp
+The following integer 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"
+.It Sy "Variable" Sy "Usage"
+.It Li "mode"
+Controls whether or not 
+.Nm
+provides internally-maintained limits and limit checking
+.Bl -tag -width "Value"
+.It Sy "Value" Sy "Meaning"
+.It Li "0"
+sensor has no internally-maintained limits
+.It Li "1"
+sensor provides its own internal limit value
+.It Li "2"
+sensor maintains an internal adjustable limit and performs its own
+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
+.Dv mode
+is set to 1 or 2)
+.It Li "type"
+Override the sensor's unit/type.
+.El
+.Pp
 For example,
 .Dl Ic modload -i type=1 swsensor
 will create a sensor of type
-.Dv ENVSYS_UNITS_SFANRPM .
+.Dv ENVSYS_UNITS_SFANRPM ,
+while
+.Dl Ic modload -i mode=1 -i limit=50 swsensor
+will create a sensor which has an initial, device-provided limit of 50.
 .Pp
 The sensor's raw value can be manually updated by modifying the
 .Xr sysctl 8
@@ -62,6 +95,17 @@
 .Xr modctl 2 ,
 .Xr envstat 8 ,
 .Xr sysctl 8
+.Sh BUGS
+The
+.Nm
+driver emulates a device with only a single sensor.
+.Pp
+The
+.Nm
+driver can only emulate one hardware-managed limit; this is assumed to
+be the
+.Dv critical-min
+limit.
 .Sh HISTORY
 The
 .Nm

Index: src/sys/dev/sysmon/swsensor.c
diff -u src/sys/dev/sysmon/swsensor.c:1.4 src/sys/dev/sysmon/swsensor.c:1.5
--- src/sys/dev/sysmon/swsensor.c:1.4	Sat Oct 23 11:24:16 2010
+++ src/sys/dev/sysmon/swsensor.c	Sat Dec 11 04:13:03 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: swsensor.c,v 1.4 2010/10/23 11:24:16 pooka Exp $ */
+/*	$NetBSD: swsensor.c,v 1.5 2010/12/11 04:13:03 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.4 2010/10/23 11:24:16 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: swsensor.c,v 1.5 2010/12/11 04:13:03 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -38,6 +38,10 @@
 
 #include <prop/proplib.h>
 
+#ifndef _MODULE
+#include "opt_modular.h"
+#endif
+
 int swsensorattach(int);
 
 static struct sysctllog *swsensor_sysctllog = NULL;
@@ -48,6 +52,10 @@
 static envsys_data_t swsensor_edata;
 
 static int32_t sw_sensor_value;
+static int32_t sw_sensor_limit;
+static int32_t sw_sensor_mode;
+static int32_t sw_sensor_defprops;
+sysmon_envsys_lim_t sw_sensor_deflims;
 
 MODULE(MODULE_CLASS_DRIVER, swsensor, NULL);
 
@@ -93,7 +101,53 @@
 {
 
 	edata->value_cur = sw_sensor_value;
-	edata->state = ENVSYS_SVALID;
+
+	/*
+	 * Set state.  If we're handling the limits ourselves, do the
+	 * compare; otherwise just assume the value is valid.
+	 */
+	if ((sw_sensor_mode == 2) && (edata->upropset & PROP_CRITMIN) &&
+	    (edata->upropset & PROP_DRIVER_LIMITS) &&
+	    (edata->value_cur < edata->limits.sel_critmin))
+		edata->state = ENVSYS_SCRITUNDER;
+	else
+		edata->state = ENVSYS_SVALID;
+}
+
+/*
+ * Sensor get/set limit routines
+ */
+
+static void     
+swsensor_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+                  sysmon_envsys_lim_t *limits, uint32_t *props)  
+{
+
+	*props = PROP_CRITMIN | PROP_DRIVER_LIMITS;
+	limits->sel_critmin = sw_sensor_limit;
+}
+
+static void     
+swsensor_set_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+                  sysmon_envsys_lim_t *limits, uint32_t *props)  
+{
+
+	if (limits == NULL) {
+		limits = &sw_sensor_deflims;
+		props = &sw_sensor_defprops;
+	}
+	if (*props & PROP_CRITMIN)
+		sw_sensor_limit = limits->sel_critmin;
+
+	/*
+	 * If the limit we can handle (crit-min) is set, and no
+	 * other limit is set, tell sysmon that the driver will
+	 * handle the limit checking.
+	 */
+	if ((*props & PROP_LIMITS) == PROP_CRITMIN)
+		*props |= PROP_DRIVER_LIMITS;
+	else
+		*props &= ~PROP_DRIVER_LIMITS;
 }
 
 /*
@@ -107,7 +161,6 @@
 	int error;
 	prop_dictionary_t pd = (prop_dictionary_t)arg;
 	prop_object_t po = NULL;
-	int pv;
 
 	swsensor_sme = sysmon_envsys_create();
 	if (swsensor_sme == NULL)
@@ -123,7 +176,6 @@
 	if (pd != NULL)
 		po = prop_dictionary_get(pd, "type");
 
-	pv = -1;
 	if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
 		swsensor_edata.units = prop_number_integer_value(po);
 	else
@@ -133,13 +185,50 @@
 	if (pd != NULL)
 		po = prop_dictionary_get(pd, "flags");
 
-	pv = -1;
 	if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
 		swsensor_edata.flags = prop_number_integer_value(po);
 	else
 		swsensor_edata.flags = 0;
 
+	/*
+	 * 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;
+
+	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);
+	}
+
 	swsensor_edata.value_cur = 0;
+
 	strlcpy(swsensor_edata.desc, "sensor", ENVSYS_DESCLEN);
 
 	error = sysmon_envsys_sensor_attach(swsensor_sme, &swsensor_edata);
@@ -156,6 +245,8 @@
 	else
 		printf("sysmon_envsys_register failed: %d\n", error);
 
+	if (error == 0)
+		printf("swsensor: initialized\n");
 	return error;
 }
 
@@ -197,7 +288,15 @@
 int
 swsensorattach(int n __unused)
 {
-	printf("%s: ", "swsensor0");
 
+#ifdef MODULAR
+	/*
+	 * Modular kernels will automatically load any built-in modules
+	 * and call their modcmd() routine, so we don't need to do it
+	 * again as part of pseudo-device configuration.
+	 */
+	return 0;
+#else
 	return swsensor_init(NULL);
+#endif
 }

Reply via email to