Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Enhance the swsensor(4) pseudo-device's capabilities to emul...



details:   https://anonhg.NetBSD.org/src/rev/292360b7c9dd
branches:  trunk
changeset: 759470:292360b7c9dd
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Sat Dec 11 04:13:03 2010 +0000

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

diffstat:

 share/man/man4/swsensor.4 |   60 +++++++++++++++++++++---
 sys/dev/sysmon/swsensor.c |  113 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 158 insertions(+), 15 deletions(-)

diffs (282 lines):

diff -r 16fb6e3efb3a -r 292360b7c9dd share/man/man4/swsensor.4
--- a/share/man/man4/swsensor.4 Sat Dec 11 03:12:10 2010 +0000
+++ b/share/man/man4/swsensor.4 Sat Dec 11 04:13:03 2010 +0000
@@ -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
diff -r 16fb6e3efb3a -r 292360b7c9dd sys/dev/sysmon/swsensor.c
--- a/sys/dev/sysmon/swsensor.c Sat Dec 11 03:12:10 2010 +0000
+++ b/sys/dev/sysmon/swsensor.c Sat Dec 11 04:13:03 2010 +0000
@@ -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
 }



Home | Main Index | Thread Index | Old Index