-rewrite dyn chip code, it now uses sensors_feature_get_type() to

identify sysfs entries. Reasons for this rewrite / bugs fixed:
 -Don't give features like alarms / sensor type / fault flag a
  compute mapping only a normal mapping
 -Don't generate features for sysfs entries like uvent, modalias, etc.
  instead only generate features for features known by
  sensors_feature_get_type()
 -Sort the list of found features logically instead of sorted in alphabet order
  of the sysfs entry. So now it starts with all in entries, then all fan and
  then all temp. Just like the order of most entries in lib/chips.c. Also
  this means that it now contains in0 - in10 in that order and not in0, in10,
  in1 - in9


git-svn-id: http://lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0@4368 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Hans de Goede committed 2007-04-10 11:51:07 +00:00
1 parent 16408d8665
commit bd74aa2390
4 files changed
+140 -127

No files matched your search

+11 -12
View File
@@ -515,27 +515,24 @@ struct feature_type_match
};
static struct feature_type_match temp_matches[] = {
{ "max", SENSORS_FEATURE_TEMP_MAX },
{ "min", SENSORS_FEATURE_TEMP_MIN },
{ "type", SENSORS_FEATURE_TEMP_SENS },
{ "hyst", SENSORS_FEATURE_TEMP_HYST },
{ "over", SENSORS_FEATURE_TEMP_OVER },
{ "max", SENSORS_FEATURE_TEMP_MAX },
{ "min", SENSORS_FEATURE_TEMP_MIN },
{ "low", SENSORS_FEATURE_TEMP_LOW },
{ "crit", SENSORS_FEATURE_TEMP_CRIT },
{ "fault", SENSORS_FEATURE_TEMP_FAULT },
{ "alarm", SENSORS_FEATURE_TEMP_ALARM },
{ "fault", SENSORS_FEATURE_TEMP_FAULT },
{ "type", SENSORS_FEATURE_TEMP_SENS },
{ 0 }
};
static struct feature_type_match in_matches[] = {
{ "max", SENSORS_FEATURE_IN_MAX },
{ "max_alarm", SENSORS_FEATURE_IN_MAX_ALARM },
{ "min", SENSORS_FEATURE_IN_MIN },
{ "min_alarm", SENSORS_FEATURE_IN_MIN_ALARM },
{ "max", SENSORS_FEATURE_IN_MAX },
{ "alarm", SENSORS_FEATURE_IN_ALARM },
{ "min_alarm", SENSORS_FEATURE_IN_MIN_ALARM },
{ "max_alarm", SENSORS_FEATURE_IN_MAX_ALARM },
{ 0 }
};
@@ -562,10 +559,11 @@ sensors_feature_type sensors_feature_get_type(
const sensors_feature_data *feature)
{
const char *name;
regex_t preg;
regmatch_t pmatch[4];
int size_first, size_second, retval, i;
struct feature_type_match *submatches;
static regex_t reg;
static regex_t *preg = NULL;
/* use sysname if exists */
if (container_of(feature, const struct sensors_chip_feature, data)->sysname)
@@ -573,11 +571,12 @@ sensors_feature_type sensors_feature_get_type(
else
name = feature->name;
regcomp(&preg, GET_TYPE_REGEX, 0);
if (!preg) {
regcomp(&reg, GET_TYPE_REGEX, 0);
preg = ®
}
retval = regexec(&preg, name, 4, pmatch, 0);
regfree(&preg);
retval = regexec(preg, name, 4, pmatch, 0);
if (retval == -1)
return SENSORS_FEATURE_UNKNOWN;
+26 -18
View File
@@ -147,11 +147,25 @@ typedef struct sensors_feature_data {
extern const sensors_feature_data *sensors_get_all_features
(sensors_chip_name name, int *nr1,int *nr2);
/* This enum contains some "magic" used by sensors_read_dynamic_chip() from
lib/sysfs.c . All the sensor-types (in, fan, temp, misc) are a multiple of
0x100 apart, and sensor features which should not have a compute_mapping to
the _input feature start at 0x?10. */
typedef enum sensors_feature_type {
SENSORS_FEATURE_TEMP = 0x0,
SENSORS_FEATURE_TEMP_ALARM,
SENSORS_FEATURE_TEMP_FAULT,
SENSORS_FEATURE_TEMP_SENS,
SENSORS_FEATURE_IN = 0x000,
SENSORS_FEATURE_IN_MIN,
SENSORS_FEATURE_IN_MAX,
SENSORS_FEATURE_IN_ALARM = 0x010,
SENSORS_FEATURE_IN_MIN_ALARM,
SENSORS_FEATURE_IN_MAX_ALARM,
SENSORS_FEATURE_FAN = 0x100,
SENSORS_FEATURE_FAN_MIN,
SENSORS_FEATURE_FAN_ALARM = 0x110,
SENSORS_FEATURE_FAN_FAULT,
SENSORS_FEATURE_FAN_DIV,
SENSORS_FEATURE_TEMP = 0x200,
SENSORS_FEATURE_TEMP_HYST,
SENSORS_FEATURE_TEMP_OVER,
SENSORS_FEATURE_TEMP_MAX,
@@ -160,24 +174,18 @@ typedef enum sensors_feature_type {
SENSORS_FEATURE_TEMP_LOW,
SENSORS_FEATURE_TEMP_LIM,
SENSORS_FEATURE_TEMP_CRIT,
SENSORS_FEATURE_IN = 0x100,
SENSORS_FEATURE_IN_ALARM,
SENSORS_FEATURE_IN_MIN,
SENSORS_FEATURE_IN_MAX,
SENSORS_FEATURE_IN_MIN_ALARM,
SENSORS_FEATURE_IN_MAX_ALARM,
SENSORS_FEATURE_FAN = 0x200,
SENSORS_FEATURE_FAN_ALARM,
SENSORS_FEATURE_FAN_FAULT,
SENSORS_FEATURE_FAN_MIN,
SENSORS_FEATURE_FAN_DIV,
SENSORS_FEATURE_TEMP_ALARM = 0x210,
SENSORS_FEATURE_TEMP_FAULT,
SENSORS_FEATURE_TEMP_SENS,
SENSORS_FEATURE_VID = 0x300,
SENSORS_FEATURE_VRM,
SENSORS_FEATURE_UNKNOWN = INT_MAX
SENSORS_FEATURE_UNKNOWN = INT_MAX,
/* special the largest number of subfeatures used, iow the
highest ## from all the 0x?## above + 1*/
SENSORS_FEATURE_MAX_SUB_FEATURES = 19
} sensors_feature_type;
sensors_feature_type sensors_feature_get_type
+99 -93
View File
@@ -21,10 +21,10 @@
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <sysfs/libsysfs.h>
#include <regex.h>
#include "data.h"
#include "error.h"
#include "access.h"
@@ -35,130 +35,136 @@ int sensors_found_sysfs = 0;
char sensors_sysfs_mount[NAME_MAX];
#define DYNAMIC_CHIP_REGEX "\\([[:alpha:]]\\{1,\\}[[:digit:]]\\{0,\\}\\)\\(\\_[[:alpha:]]\\{1,\\}\\)\\{0,1\\}"
static int sensors_read_dynamic_chip_check_mapping(
sensors_chip_feature *minor,
sensors_chip_feature *major,
regmatch_t *pmatch)
{
if (pmatch[1].rm_so == -1 || pmatch[2].rm_so == -1 ||
strncmp(minor->data.name, major->data.name,
pmatch[1].rm_eo - pmatch[1].rm_so)) {
return 0;
} else {
minor->data.mapping =
minor->data.compute_mapping =
major->data.number;
return 1;
}
}
#define MAX_SENSORS_PER_TYPE 16
static
sensors_chip_features sensors_read_dynamic_chip(struct sysfs_device *sysdir)
{
int fnum = 1, i, last_major = -1;
int i, type, fnum = 1;
struct sysfs_attribute *attr;
struct dlist *attrs;
sensors_chip_features ret = {0, 0};
sensors_chip_feature features[256], *dyn_features;
regex_t preg;
regmatch_t pmatch[3];
/* room for all 3 (in, fan, temp) types, with all their subfeatures
+ misc features. We use a large sparse table at first to store all
found features, so that we can store them sorted at type and index
and then later create a dense sorted table */
sensors_chip_feature features[MAX_SENSORS_PER_TYPE *
SENSORS_FEATURE_MAX_SUB_FEATURES * 3 +
SENSORS_FEATURE_MAX_SUB_FEATURES];
sensors_chip_feature *dyn_features;
char *name;
attrs = sysfs_get_device_attributes(sysdir);
if (attrs == NULL)
return ret;
regcomp(&preg, DYNAMIC_CHIP_REGEX, 0);
memset(features, 0, sizeof(features));
dlist_for_each_data(attrs, attr, struct sysfs_attribute) {
sensors_chip_feature feature = { { 0, }, 0, };
sensors_chip_feature feature = { { 0, }, 0, };
name = attr->name;
if (!strcmp(name, "name")) {
ret.prefix = strndup(attr->value, strlen(attr->value) - 1);
continue;
} else if (regexec(&preg, name, 3, pmatch, 0) != 0) {
}
/* check for _input extension and remove */
i = strlen(name);
if (i > 6 && !strcmp(name + i - 6, "_input"))
feature.data.name = strndup(name, i-6);
else
feature.data.name = strdup(name);
type = sensors_feature_get_type(&feature.data);
if (type == SENSORS_FEATURE_UNKNOWN) {
free((char *)feature.data.name);
continue;
}
/* Get N as in this is the N-th in / fan / temp sensor */
switch (type & 0xFF00) {
case SENSORS_FEATURE_IN:
i = strtol(name + 2, NULL, 10);
break;
case SENSORS_FEATURE_FAN:
i = strtol(name + 3, NULL, 10);
if (i) i--;
break;
case SENSORS_FEATURE_TEMP:
i = strtol(name + 4, NULL, 10);
if (i) i--;
break;
case SENSORS_FEATURE_VID: /* first misc feature */
i = 0;
break;
}
if (i >= MAX_SENSORS_PER_TYPE) {
fprintf(stderr, "libsensors error, more sensors of one"
" type then MAX_SENSORS_PER_TYPE, ignoring "
"feature: %s\n", name);
free((char *)feature.data.name);
continue;
}
feature.data.number = fnum;
feature.data.mode = (attr->method & (SYSFS_METHOD_SHOW|SYSFS_METHOD_STORE)) ==
(SYSFS_METHOD_SHOW|SYSFS_METHOD_STORE) ?
SENSORS_MODE_RW :
(attr->method & SYSFS_METHOD_SHOW) ? SENSORS_MODE_R :
(attr->method & SYSFS_METHOD_STORE) ? SENSORS_MODE_W :
SENSORS_MODE_NO_RW;
feature.data.mapping = SENSORS_NO_MAPPING;
feature.data.compute_mapping = SENSORS_NO_MAPPING;
if (pmatch[2].rm_so != -1) {
if (!strcmp(name + pmatch[2].rm_so, "_input")) {
int last_match;
/* copy only the part before the _ */
feature.data.name = strndup(name,
pmatch[1].rm_eo - pmatch[1].rm_so);
/* check if the features previously read are sub devices of this major
and update their mapping accordingly */
last_match = fnum - 1;
for(i = fnum - 2; i >= 0; i--) {
if (regexec(&preg, features[i].data.name, 3, pmatch, 0) == -1 ||
!sensors_read_dynamic_chip_check_mapping(&features[i],
&feature, pmatch)) {
break;
} else {
last_match = i;
}
}
/* if so the major should be in the list before any minor feature,
so swap with the oldest read */
if (last_match < fnum - 1) {
sensors_chip_feature tmp = features[last_match];
features[last_match] = feature;
features[fnum - 1] = tmp;
last_major = last_match;
goto NEXT_NUM; /* NOTE: goto used */
} else {
last_major = fnum - 1;
}
} else {
feature.data.name = strdup(name);
if (last_major != -1 &&
!sensors_read_dynamic_chip_check_mapping(&feature,
&features[last_major], pmatch)) {
last_major = -1; /* no more features for current major */
}
}
} else {
feature.data.name = strdup(name);
/* "calculate" a place to store the feature in our sparse,
sorted table */
i = (type >> 8) * MAX_SENSORS_PER_TYPE *
SENSORS_FEATURE_MAX_SUB_FEATURES +
i * SENSORS_FEATURE_MAX_SUB_FEATURES + (type & 0xFF);
if (features[i].data.name) {
fprintf(stderr, "libsensors error, trying to add dupli"
"cate feature: %s to dynamic feature table\n",
name);
free((char *)feature.data.name);
continue;
}
/* fill in the other feature members */
feature.data.number = i + 1;
features[fnum - 1] = feature;
NEXT_NUM:
if ( (type & 0xFF00) == SENSORS_FEATURE_VID ||
(type & 0x00FF) == 0) {
/* misc sensor or main feature */
feature.data.mapping = SENSORS_NO_MAPPING;
feature.data.compute_mapping = SENSORS_NO_MAPPING;
} else if (type & 0x10) {
/* sub feature without compute mapping */
feature.data.mapping = i -
i % SENSORS_FEATURE_MAX_SUB_FEATURES + 1;
feature.data.compute_mapping = SENSORS_NO_MAPPING;
} else {
feature.data.mapping = i -
i % SENSORS_FEATURE_MAX_SUB_FEATURES + 1;
feature.data.compute_mapping = feature.data.mapping;
}
feature.data.mode =
(attr->method & (SYSFS_METHOD_SHOW|SYSFS_METHOD_STORE))
== (SYSFS_METHOD_SHOW|SYSFS_METHOD_STORE) ?
SENSORS_MODE_RW : (attr->method & SYSFS_METHOD_SHOW) ?
SENSORS_MODE_R : (attr->method & SYSFS_METHOD_STORE) ?
SENSORS_MODE_W : SENSORS_MODE_NO_RW;
features[i] = feature;
fnum++;
}
regfree(&preg);
dyn_features = malloc(sizeof(sensors_chip_feature) * fnum);
dyn_features = calloc(fnum, sizeof(sensors_chip_feature));
if (dyn_features == NULL) {
sensors_fatal_error(__FUNCTION__,"Out of memory");
}
for(i = 0; i < fnum - 1; i++) {
dyn_features[i] = features[i];
fnum = 0;
for(i = 0; i < sizeof(features)/sizeof(sensors_chip_feature); i++) {
if (features[i].data.name) {
dyn_features[fnum] = features[i];
fnum++;
}
}
dyn_features[fnum - 1].data.name = 0;
ret.feature = dyn_features;
+4 -4
View File
@@ -110,9 +110,9 @@ static void print_generic_chip_temp(const sensors_chip_name *name,
double val, max, min, lim = 0.0;
char *label;
int valid, type;
const int size = SENSORS_FEATURE_TEMP_CRIT - SENSORS_FEATURE_TEMP;
short has_features[SENSORS_FEATURE_TEMP_CRIT - SENSORS_FEATURE_TEMP] = {0, 0, 0, 0, 0, 0, 0, 0, 0 };
double feature_vals[SENSORS_FEATURE_TEMP_CRIT - SENSORS_FEATURE_TEMP] = {0.0, };
const int size = SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP;
short has_features[SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP] = {0, };
double feature_vals[SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP] = {0.0, };
if (sensors_get_label_and_valid(*name, feature->number, &label, &valid)) {
free(label);
@@ -254,7 +254,7 @@ static void print_generic_chip_in(const sensors_chip_name *name,
{
const int size = SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN;
int valid;
short has_features[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0, 0, 0, 0, 0 };
short has_features[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0, };
double feature_vals[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0.0, };
double val, alarm_max, alarm_min;
char *label;