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 }