2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-31 14:25:39 +00:00

Introduce a separate type for main features. Make subfeatures map to

the real main feature rather than the first subfeature.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0@4838 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare
2007-09-23 12:16:50 +00:00
parent 65f1d1f1cd
commit da7b4e48da
6 changed files with 136 additions and 130 deletions

View File

@@ -105,6 +105,24 @@ sensors_lookup_subfeature_nr(const sensors_chip_name *chip,
return NULL;
}
/* Look up a feature in the intern chip list, and return a pointer to it.
Do not modify the struct the return value points to! Returns NULL if
not found.*/
static const sensors_feature *
sensors_lookup_feature_nr(const sensors_chip_name *chip, int feat_nr)
{
int i;
for (i = 0; i < sensors_proc_chips_count; i++)
if (sensors_match_chip(&sensors_proc_chips[i].chip, chip)) {
if (feat_nr < 0 ||
feat_nr >= sensors_proc_chips[i].feature_count)
return NULL;
return sensors_proc_chips[i].feature + feat_nr;
}
return NULL;
}
/* Look up a resource in the intern chip list, and return a pointer to it.
Do not modify the struct the return value points to! Returns NULL if
not found.*/
@@ -208,12 +226,11 @@ int sensors_get_value(const sensors_chip_name *name, int subfeat_nr,
double *result)
{
const sensors_subfeature *subfeature;
const sensors_subfeature *alt_feature;
const sensors_feature *feature;
const sensors_chip *chip;
const sensors_expr *expr = NULL;
double val;
int res, i;
int final_expr = 0;
if (sensors_chip_name_has_wildcards(name))
return -SENSORS_ERR_WILDCARDS;
@@ -221,20 +238,17 @@ int sensors_get_value(const sensors_chip_name *name, int subfeat_nr,
return -SENSORS_ERR_NO_ENTRY;
if (subfeature->flags & SENSORS_COMPUTE_MAPPING)
alt_feature = sensors_lookup_subfeature_nr(name,
feature = sensors_lookup_feature_nr(name,
subfeature->mapping);
else
alt_feature = NULL;
feature = NULL;
if (!(subfeature->flags & SENSORS_MODE_R))
return -SENSORS_ERR_ACCESS_R;
for (chip = NULL;
!expr && (chip = sensors_for_all_config_chips(name, chip));)
for (i = 0; !final_expr && (i < chip->computes_count); i++) {
if (!strcmp(subfeature->name, chip->computes[i].name)) {
expr = chip->computes[i].from_proc;
final_expr = 1;
} else if (alt_feature && !strcmp(alt_feature->name,
for (i = 0; !expr && (i < chip->computes_count); i++) {
if (feature && !strcmp(feature->name,
chip->computes[i].name)) {
expr = chip->computes[i].from_proc;
}
@@ -255,11 +269,10 @@ int sensors_set_value(const sensors_chip_name *name, int subfeat_nr,
double value)
{
const sensors_subfeature *subfeature;
const sensors_subfeature *alt_feature;
const sensors_feature *feature;
const sensors_chip *chip;
const sensors_expr *expr = NULL;
int i, res;
int final_expr = 0;
double to_write;
if (sensors_chip_name_has_wildcards(name))
@@ -268,23 +281,21 @@ int sensors_set_value(const sensors_chip_name *name, int subfeat_nr,
return -SENSORS_ERR_NO_ENTRY;
if (subfeature->flags & SENSORS_COMPUTE_MAPPING)
alt_feature = sensors_lookup_subfeature_nr(name,
feature = sensors_lookup_feature_nr(name,
subfeature->mapping);
else
alt_feature = NULL;
feature = NULL;
if (!(subfeature->flags & SENSORS_MODE_W))
return -SENSORS_ERR_ACCESS_W;
for (chip = NULL;
!expr && (chip = sensors_for_all_config_chips(name, chip));)
for (i = 0; !final_expr && (i < chip->computes_count); i++)
if (!strcmp(subfeature->name, chip->computes[i].name)) {
expr = chip->computes->to_proc;
final_expr = 1;
} else if (alt_feature && !strcmp(alt_feature->name,
for (i = 0; !expr && (i < chip->computes_count); i++) {
if (feature && !strcmp(feature->name,
chip->computes[i].name)) {
expr = chip->computes[i].to_proc;
}
}
to_write = value;
if (expr)
@@ -367,8 +378,7 @@ sensors_get_all_subfeatures(const sensors_chip_name *name,
if (*nr >= sensors_proc_chips[i].subfeature_count)
return NULL; /* end of list */
subfeature = &sensors_proc_chips[i].subfeature[(*nr)++];
if (subfeature->number == feature->first_subfeature ||
subfeature->mapping == feature->first_subfeature)
if (subfeature->mapping == feature->number)
return subfeature;
return NULL; /* end of subfeature list */
}

View File

@@ -134,10 +134,9 @@ data structures.
\fBconst sensors_subfeature *sensors_get_all_subfeatures(const sensors_chip_name *name, const sensors_feature *feature, int *nr);\fP
.br
This returns all subfeatures of a given main feature (including that
main feature itself, in first position.) nr is an internally used
variable. Set it to zero to start at the begin of the list. If no more
subfeatures are found NULL is returned.
This returns all subfeatures of a given main feature. nr is an internally
used variable. Set it to zero to start at the begin of the list. If no
more subfeatures are found NULL is returned.
Do not try to change the returned structure; you will corrupt internal
data structures.

View File

@@ -124,6 +124,16 @@ const sensors_chip_name *sensors_get_detected_chips(const sensors_chip_name
mapping is available */
#define SENSORS_NO_MAPPING -1
/* These must match the subfeature constants below (shifted by 8 bits) */
typedef enum sensors_feature_type {
SENSORS_FEATURE_IN = 0x00,
SENSORS_FEATURE_FAN = 0x01,
SENSORS_FEATURE_TEMP = 0x02,
SENSORS_FEATURE_VID = 0x10,
SENSORS_FEATURE_BEEP_ENABLE = 0x11,
SENSORS_FEATURE_UNKNOWN = INT_MAX,
} sensors_feature_type;
/* This enum contains some "magic" used by sensors_read_dynamic_chip() from
lib/sysfs.c. All the sensor types (in, fan, temp, vid) are a multiple of
0x100 apart, and sensor subfeatures which should not have a compute
@@ -169,8 +179,9 @@ typedef enum sensors_subfeature_type {
/* Data about a single chip feature (or category leader) */
struct sensors_feature {
char *name;
int number;
sensors_feature_type type;
int first_subfeature;
sensors_subfeature_type type;
};
/* Data about a single chip subfeature:
@@ -201,10 +212,9 @@ typedef struct sensors_subfeature {
const sensors_feature *
sensors_get_features(const sensors_chip_name *name, int *nr);
/* This returns all subfeatures of a given main feature (including that
main feature itself, in first position.) nr is an internally used
variable. Set it to zero to start at the begin of the list. If no more
features are found NULL is returned.
/* This returns all subfeatures of a given main feature. nr is an internally
used variable. Set it to zero to start at the begin of the list. If no
more features are found NULL is returned.
Do not try to change the returned structure; you will corrupt internal
data structures. */
const sensors_subfeature *

View File

@@ -65,6 +65,25 @@ int get_type_scaling(int type)
}
}
static
char *get_feature_name(sensors_feature_type ftype, char *sfname)
{
char *name, *underscore;
switch (ftype) {
case SENSORS_FEATURE_IN:
case SENSORS_FEATURE_FAN:
case SENSORS_FEATURE_TEMP:
underscore = strchr(sfname, '_');
name = strndup(sfname, underscore - sfname);
break;
default:
name = strdup(sfname);
}
return name;
}
/* Static mappings for use by sensors_subfeature_get_type() */
struct subfeature_type_match
{
@@ -160,12 +179,14 @@ sensors_subfeature_type sensors_subfeature_get_type(const char *name, int *nr)
static int sensors_read_dynamic_chip(sensors_chip_features *chip,
struct sysfs_device *sysdir)
{
int i, type, fnum = 0;
int i, fnum = 0, sfnum = 0, prev_slot;
struct sysfs_attribute *attr;
struct dlist *attrs;
sensors_subfeature *all_subfeatures;
sensors_subfeature *dyn_subfeatures;
sensors_feature *dyn_features;
sensors_feature_type ftype;
sensors_subfeature_type sftype;
attrs = sysfs_get_device_attributes(sysdir);
@@ -184,12 +205,12 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
char *name = attr->name;
int nr;
type = sensors_subfeature_get_type(name, &nr);
if (type == SENSORS_SUBFEATURE_UNKNOWN)
sftype = sensors_subfeature_get_type(name, &nr);
if (sftype == SENSORS_SUBFEATURE_UNKNOWN)
continue;
/* Adjust the channel number */
switch (type & 0xFF00) {
switch (sftype & 0xFF00) {
case SENSORS_SUBFEATURE_FAN_INPUT:
case SENSORS_SUBFEATURE_TEMP_INPUT:
if (nr)
@@ -206,7 +227,7 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
/* "calculate" a place to store the subfeature in our sparse,
sorted table */
switch (type) {
switch (sftype) {
case SENSORS_SUBFEATURE_VID:
i = nr + MAX_SENSORS_PER_TYPE * MAX_SUBFEATURES * 6;
break;
@@ -215,10 +236,10 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
MAX_SENSORS_PER_TYPE;
break;
default:
i = (type >> 8) * MAX_SENSORS_PER_TYPE *
i = (sftype >> 8) * MAX_SENSORS_PER_TYPE *
MAX_SUBFEATURES * 2 + nr * MAX_SUBFEATURES * 2 +
((type & 0x10) >> 4) * MAX_SUBFEATURES +
(type & 0x0F);
((sftype & 0x10) >> 4) * MAX_SUBFEATURES +
(sftype & 0x0F);
}
if (all_subfeatures[i].name) {
@@ -229,93 +250,75 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
}
/* fill in the subfeature members */
all_subfeatures[i].type = type;
/* check for _input extension and remove */
nr = strlen(name);
if (nr > 6 && !strcmp(name + nr - 6, "_input"))
all_subfeatures[i].name = strndup(name, nr - 6);
else
all_subfeatures[i].name = strdup(name);
if ((type & 0x00FF) == 0) {
/* main subfeature */
all_subfeatures[i].mapping = SENSORS_NO_MAPPING;
} else {
/* The mapping is set below after numbering */
if (!(type & 0x10))
all_subfeatures[i].flags |= SENSORS_COMPUTE_MAPPING;
}
all_subfeatures[i].type = sftype;
all_subfeatures[i].name = strdup(name);
if (!(sftype & 0x10))
all_subfeatures[i].flags |= SENSORS_COMPUTE_MAPPING;
if (attr->method & SYSFS_METHOD_SHOW)
all_subfeatures[i].flags |= SENSORS_MODE_R;
if (attr->method & SYSFS_METHOD_STORE)
all_subfeatures[i].flags |= SENSORS_MODE_W;
fnum++;
sfnum++;
}
if (!fnum) { /* No subfeature */
if (!sfnum) { /* No subfeature */
chip->subfeature = NULL;
goto exit_free;
}
dyn_subfeatures = calloc(fnum, sizeof(sensors_subfeature));
if (dyn_subfeatures == NULL) {
sensors_fatal_error(__FUNCTION__, "Out of memory");
}
fnum = 0;
/* How many main features? */
prev_slot = -1;
for (i = 0; i < ALL_POSSIBLE_SUBFEATURES; i++) {
if (all_subfeatures[i].name) {
dyn_subfeatures[fnum] = all_subfeatures[i];
if (!all_subfeatures[i].name)
continue;
if (i >= MAX_SENSORS_PER_TYPE * MAX_SUBFEATURES * 6 ||
i / (MAX_SUBFEATURES * 2) != prev_slot) {
fnum++;
prev_slot = i / (MAX_SUBFEATURES * 2);
}
}
/* Number the subfeatures linearly, so that subfeature number N is at
position N in the array. This allows for O(1) look-ups. */
for (i = 0; i < fnum; i++) {
int j;
dyn_subfeatures = calloc(sfnum, sizeof(sensors_subfeature));
dyn_features = calloc(fnum, sizeof(sensors_feature));
if (!dyn_subfeatures || !dyn_features)
sensors_fatal_error(__FUNCTION__, "Out of memory");
dyn_subfeatures[i].number = i;
if (dyn_subfeatures[i].mapping == SENSORS_NO_MAPPING) {
/* Main feature, set the mapping field of all its
subfeatures */
for (j = i + 1; j < fnum &&
dyn_subfeatures[j].mapping != SENSORS_NO_MAPPING;
j++)
dyn_subfeatures[j].mapping = i;
/* Copy from the sparse array to the compact array */
sfnum = 0;
fnum = -1;
prev_slot = -1;
for (i = 0; i < ALL_POSSIBLE_SUBFEATURES; i++) {
if (!all_subfeatures[i].name)
continue;
/* New main feature? */
if (i >= MAX_SENSORS_PER_TYPE * MAX_SUBFEATURES * 6 ||
i / (MAX_SUBFEATURES * 2) != prev_slot) {
ftype = all_subfeatures[i].type >> 8;
fnum++;
prev_slot = i / (MAX_SUBFEATURES * 2);
dyn_features[fnum].name = get_feature_name(ftype,
all_subfeatures[i].name);
dyn_features[fnum].number = fnum;
dyn_features[fnum].first_subfeature = sfnum;
dyn_features[fnum].type = ftype;
}
dyn_subfeatures[sfnum] = all_subfeatures[i];
dyn_subfeatures[sfnum].number = sfnum;
/* Back to the feature */
dyn_subfeatures[sfnum].mapping = fnum;
sfnum++;
}
chip->subfeature = dyn_subfeatures;
chip->subfeature_count = fnum;
/* And now the main features */
fnum = 0;
for (i = 0; i < chip->subfeature_count; i++) {
if (chip->subfeature[i].mapping == SENSORS_NO_MAPPING)
fnum++;
}
dyn_features = calloc(fnum, sizeof(sensors_feature));
if (dyn_features == NULL) {
sensors_fatal_error(__FUNCTION__, "Out of memory");
}
fnum = 0;
for (i = 0; i < chip->subfeature_count; i++) {
if (chip->subfeature[i].mapping == SENSORS_NO_MAPPING) {
dyn_features[fnum].name = strdup(chip->subfeature[i].name);
dyn_features[fnum].first_subfeature = i;
dyn_features[fnum].type = chip->subfeature[i].type;
fnum++;
}
}
chip->subfeature_count = sfnum;
chip->feature = dyn_features;
chip->feature_count = fnum;
chip->feature_count = ++fnum;
exit_free:
free(all_subfeatures);
@@ -544,19 +547,11 @@ int sensors_read_sysfs_attr(const sensors_chip_name *name, int subfeat_nr,
const sensors_subfeature *subfeature;
char n[NAME_MAX];
FILE *f;
const char *suffix = "";
if (!(subfeature = sensors_lookup_subfeature_nr(name, subfeat_nr)))
return -SENSORS_ERR_NO_ENTRY;
/* REVISIT: this is a ugly hack */
if (subfeature->type == SENSORS_SUBFEATURE_IN_INPUT
|| subfeature->type == SENSORS_SUBFEATURE_FAN_INPUT
|| subfeature->type == SENSORS_SUBFEATURE_TEMP_INPUT)
suffix = "_input";
snprintf(n, NAME_MAX, "%s/%s%s", name->path, subfeature->name,
suffix);
snprintf(n, NAME_MAX, "%s/%s", name->path, subfeature->name);
if ((f = fopen(n, "r"))) {
int res = fscanf(f, "%lf", value);
fclose(f);
@@ -575,19 +570,11 @@ int sensors_write_sysfs_attr(const sensors_chip_name *name, int subfeat_nr,
const sensors_subfeature *subfeature;
char n[NAME_MAX];
FILE *f;
const char *suffix = "";
if (!(subfeature = sensors_lookup_subfeature_nr(name, subfeat_nr)))
return -SENSORS_ERR_NO_ENTRY;
/* REVISIT: this is a ugly hack */
if (subfeature->type == SENSORS_SUBFEATURE_IN_INPUT
|| subfeature->type == SENSORS_SUBFEATURE_FAN_INPUT
|| subfeature->type == SENSORS_SUBFEATURE_TEMP_INPUT)
suffix = "_input";
snprintf(n, NAME_MAX, "%s/%s%s", name->path, subfeature->name,
suffix);
snprintf(n, NAME_MAX, "%s/%s", name->path, subfeature->name);
if ((f = fopen(n, "w"))) {
value *= get_type_scaling(subfeature->type);
fprintf(f, "%d", (int) value);

View File

@@ -373,19 +373,19 @@ FeatureDescriptor * generateChipFeatures (const sensors_chip_name *chip)
nr = 0;
while ((sensor = sensors_get_features(chip, &nr))) {
switch (sensor->type) {
case SENSORS_SUBFEATURE_TEMP_INPUT:
case SENSORS_FEATURE_TEMP:
fillChipTemperature(&features[count], chip, sensor);
break;
case SENSORS_SUBFEATURE_IN_INPUT:
case SENSORS_FEATURE_IN:
fillChipVoltage(&features[count], chip, sensor);
break;
case SENSORS_SUBFEATURE_FAN_INPUT:
case SENSORS_FEATURE_FAN:
fillChipFan(&features[count], chip, sensor);
break;
case SENSORS_SUBFEATURE_VID:
case SENSORS_FEATURE_VID:
fillChipVid(&features[count], chip, sensor);
break;
case SENSORS_SUBFEATURE_BEEP_ENABLE:
case SENSORS_FEATURE_BEEP_ENABLE:
fillChipBeepEnable(&features[count], chip, sensor);
break;
default:

View File

@@ -435,19 +435,19 @@ void print_chip(const sensors_chip_name *name)
i = 0;
while ((feature = sensors_get_features(name, &i))) {
switch (feature->type) {
case SENSORS_SUBFEATURE_TEMP_INPUT:
case SENSORS_FEATURE_TEMP:
print_chip_temp(name, feature, label_size);
break;
case SENSORS_SUBFEATURE_IN_INPUT:
case SENSORS_FEATURE_IN:
print_chip_in(name, feature, label_size);
break;
case SENSORS_SUBFEATURE_FAN_INPUT:
case SENSORS_FEATURE_FAN:
print_chip_fan(name, feature, label_size);
break;
case SENSORS_SUBFEATURE_VID:
case SENSORS_FEATURE_VID:
print_chip_vid(name, feature, label_size);
break;
case SENSORS_SUBFEATURE_BEEP_ENABLE:
case SENSORS_FEATURE_BEEP_ENABLE:
print_chip_beep_enable(name, feature, label_size);
break;
default: