2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-09-02 15:25:38 +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; 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. /* 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 Do not modify the struct the return value points to! Returns NULL if
not found.*/ not found.*/
@@ -208,12 +226,11 @@ int sensors_get_value(const sensors_chip_name *name, int subfeat_nr,
double *result) double *result)
{ {
const sensors_subfeature *subfeature; const sensors_subfeature *subfeature;
const sensors_subfeature *alt_feature; const sensors_feature *feature;
const sensors_chip *chip; const sensors_chip *chip;
const sensors_expr *expr = NULL; const sensors_expr *expr = NULL;
double val; double val;
int res, i; int res, i;
int final_expr = 0;
if (sensors_chip_name_has_wildcards(name)) if (sensors_chip_name_has_wildcards(name))
return -SENSORS_ERR_WILDCARDS; 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; return -SENSORS_ERR_NO_ENTRY;
if (subfeature->flags & SENSORS_COMPUTE_MAPPING) if (subfeature->flags & SENSORS_COMPUTE_MAPPING)
alt_feature = sensors_lookup_subfeature_nr(name, feature = sensors_lookup_feature_nr(name,
subfeature->mapping); subfeature->mapping);
else else
alt_feature = NULL; feature = NULL;
if (!(subfeature->flags & SENSORS_MODE_R)) if (!(subfeature->flags & SENSORS_MODE_R))
return -SENSORS_ERR_ACCESS_R; return -SENSORS_ERR_ACCESS_R;
for (chip = NULL; for (chip = NULL;
!expr && (chip = sensors_for_all_config_chips(name, chip));) !expr && (chip = sensors_for_all_config_chips(name, chip));)
for (i = 0; !final_expr && (i < chip->computes_count); i++) { for (i = 0; !expr && (i < chip->computes_count); i++) {
if (!strcmp(subfeature->name, chip->computes[i].name)) { if (feature && !strcmp(feature->name,
expr = chip->computes[i].from_proc;
final_expr = 1;
} else if (alt_feature && !strcmp(alt_feature->name,
chip->computes[i].name)) { chip->computes[i].name)) {
expr = chip->computes[i].from_proc; expr = chip->computes[i].from_proc;
} }
@@ -255,11 +269,10 @@ int sensors_set_value(const sensors_chip_name *name, int subfeat_nr,
double value) double value)
{ {
const sensors_subfeature *subfeature; const sensors_subfeature *subfeature;
const sensors_subfeature *alt_feature; const sensors_feature *feature;
const sensors_chip *chip; const sensors_chip *chip;
const sensors_expr *expr = NULL; const sensors_expr *expr = NULL;
int i, res; int i, res;
int final_expr = 0;
double to_write; double to_write;
if (sensors_chip_name_has_wildcards(name)) 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; return -SENSORS_ERR_NO_ENTRY;
if (subfeature->flags & SENSORS_COMPUTE_MAPPING) if (subfeature->flags & SENSORS_COMPUTE_MAPPING)
alt_feature = sensors_lookup_subfeature_nr(name, feature = sensors_lookup_feature_nr(name,
subfeature->mapping); subfeature->mapping);
else else
alt_feature = NULL; feature = NULL;
if (!(subfeature->flags & SENSORS_MODE_W)) if (!(subfeature->flags & SENSORS_MODE_W))
return -SENSORS_ERR_ACCESS_W; return -SENSORS_ERR_ACCESS_W;
for (chip = NULL; for (chip = NULL;
!expr && (chip = sensors_for_all_config_chips(name, chip));) !expr && (chip = sensors_for_all_config_chips(name, chip));)
for (i = 0; !final_expr && (i < chip->computes_count); i++) for (i = 0; !expr && (i < chip->computes_count); i++) {
if (!strcmp(subfeature->name, chip->computes[i].name)) { if (feature && !strcmp(feature->name,
expr = chip->computes->to_proc;
final_expr = 1;
} else if (alt_feature && !strcmp(alt_feature->name,
chip->computes[i].name)) { chip->computes[i].name)) {
expr = chip->computes[i].to_proc; expr = chip->computes[i].to_proc;
} }
}
to_write = value; to_write = value;
if (expr) if (expr)
@@ -367,8 +378,7 @@ sensors_get_all_subfeatures(const sensors_chip_name *name,
if (*nr >= sensors_proc_chips[i].subfeature_count) if (*nr >= sensors_proc_chips[i].subfeature_count)
return NULL; /* end of list */ return NULL; /* end of list */
subfeature = &sensors_proc_chips[i].subfeature[(*nr)++]; subfeature = &sensors_proc_chips[i].subfeature[(*nr)++];
if (subfeature->number == feature->first_subfeature || if (subfeature->mapping == feature->number)
subfeature->mapping == feature->first_subfeature)
return subfeature; return subfeature;
return NULL; /* end of subfeature list */ 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 \fBconst sensors_subfeature *sensors_get_all_subfeatures(const sensors_chip_name *name, const sensors_feature *feature, int *nr);\fP
.br .br
This returns all subfeatures of a given main feature (including that This returns all subfeatures of a given main feature. nr is an internally
main feature itself, in first position.) nr is an internally used used variable. Set it to zero to start at the begin of the list. If no
variable. Set it to zero to start at the begin of the list. If no more more subfeatures are found NULL is returned.
subfeatures are found NULL is returned.
Do not try to change the returned structure; you will corrupt internal Do not try to change the returned structure; you will corrupt internal
data structures. data structures.

View File

@@ -124,6 +124,16 @@ const sensors_chip_name *sensors_get_detected_chips(const sensors_chip_name
mapping is available */ mapping is available */
#define SENSORS_NO_MAPPING -1 #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 /* 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 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 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) */ /* Data about a single chip feature (or category leader) */
struct sensors_feature { struct sensors_feature {
char *name; char *name;
int number;
sensors_feature_type type;
int first_subfeature; int first_subfeature;
sensors_subfeature_type type;
}; };
/* Data about a single chip subfeature: /* Data about a single chip subfeature:
@@ -201,10 +212,9 @@ typedef struct sensors_subfeature {
const sensors_feature * const sensors_feature *
sensors_get_features(const sensors_chip_name *name, int *nr); sensors_get_features(const sensors_chip_name *name, int *nr);
/* This returns all subfeatures of a given main feature (including that /* This returns all subfeatures of a given main feature. nr is an internally
main feature itself, in first position.) nr is an internally used used variable. Set it to zero to start at the begin of the list. If no
variable. Set it to zero to start at the begin of the list. If no more more features are found NULL is returned.
features are found NULL is returned.
Do not try to change the returned structure; you will corrupt internal Do not try to change the returned structure; you will corrupt internal
data structures. */ data structures. */
const sensors_subfeature * 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() */ /* Static mappings for use by sensors_subfeature_get_type() */
struct subfeature_type_match 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, static int sensors_read_dynamic_chip(sensors_chip_features *chip,
struct sysfs_device *sysdir) struct sysfs_device *sysdir)
{ {
int i, type, fnum = 0; int i, fnum = 0, sfnum = 0, prev_slot;
struct sysfs_attribute *attr; struct sysfs_attribute *attr;
struct dlist *attrs; struct dlist *attrs;
sensors_subfeature *all_subfeatures; sensors_subfeature *all_subfeatures;
sensors_subfeature *dyn_subfeatures; sensors_subfeature *dyn_subfeatures;
sensors_feature *dyn_features; sensors_feature *dyn_features;
sensors_feature_type ftype;
sensors_subfeature_type sftype;
attrs = sysfs_get_device_attributes(sysdir); attrs = sysfs_get_device_attributes(sysdir);
@@ -184,12 +205,12 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
char *name = attr->name; char *name = attr->name;
int nr; int nr;
type = sensors_subfeature_get_type(name, &nr); sftype = sensors_subfeature_get_type(name, &nr);
if (type == SENSORS_SUBFEATURE_UNKNOWN) if (sftype == SENSORS_SUBFEATURE_UNKNOWN)
continue; continue;
/* Adjust the channel number */ /* Adjust the channel number */
switch (type & 0xFF00) { switch (sftype & 0xFF00) {
case SENSORS_SUBFEATURE_FAN_INPUT: case SENSORS_SUBFEATURE_FAN_INPUT:
case SENSORS_SUBFEATURE_TEMP_INPUT: case SENSORS_SUBFEATURE_TEMP_INPUT:
if (nr) 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, /* "calculate" a place to store the subfeature in our sparse,
sorted table */ sorted table */
switch (type) { switch (sftype) {
case SENSORS_SUBFEATURE_VID: case SENSORS_SUBFEATURE_VID:
i = nr + MAX_SENSORS_PER_TYPE * MAX_SUBFEATURES * 6; i = nr + MAX_SENSORS_PER_TYPE * MAX_SUBFEATURES * 6;
break; break;
@@ -215,10 +236,10 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
MAX_SENSORS_PER_TYPE; MAX_SENSORS_PER_TYPE;
break; break;
default: default:
i = (type >> 8) * MAX_SENSORS_PER_TYPE * i = (sftype >> 8) * MAX_SENSORS_PER_TYPE *
MAX_SUBFEATURES * 2 + nr * MAX_SUBFEATURES * 2 + MAX_SUBFEATURES * 2 + nr * MAX_SUBFEATURES * 2 +
((type & 0x10) >> 4) * MAX_SUBFEATURES + ((sftype & 0x10) >> 4) * MAX_SUBFEATURES +
(type & 0x0F); (sftype & 0x0F);
} }
if (all_subfeatures[i].name) { if (all_subfeatures[i].name) {
@@ -229,93 +250,75 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip,
} }
/* fill in the subfeature members */ /* fill in the subfeature members */
all_subfeatures[i].type = type; all_subfeatures[i].type = sftype;
all_subfeatures[i].name = strdup(name);
/* check for _input extension and remove */ if (!(sftype & 0x10))
nr = strlen(name); all_subfeatures[i].flags |= SENSORS_COMPUTE_MAPPING;
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;
}
if (attr->method & SYSFS_METHOD_SHOW) if (attr->method & SYSFS_METHOD_SHOW)
all_subfeatures[i].flags |= SENSORS_MODE_R; all_subfeatures[i].flags |= SENSORS_MODE_R;
if (attr->method & SYSFS_METHOD_STORE) if (attr->method & SYSFS_METHOD_STORE)
all_subfeatures[i].flags |= SENSORS_MODE_W; all_subfeatures[i].flags |= SENSORS_MODE_W;
fnum++; sfnum++;
} }
if (!fnum) { /* No subfeature */ if (!sfnum) { /* No subfeature */
chip->subfeature = NULL; chip->subfeature = NULL;
goto exit_free; goto exit_free;
} }
dyn_subfeatures = calloc(fnum, sizeof(sensors_subfeature)); /* How many main features? */
if (dyn_subfeatures == NULL) { prev_slot = -1;
sensors_fatal_error(__FUNCTION__, "Out of memory");
}
fnum = 0;
for (i = 0; i < ALL_POSSIBLE_SUBFEATURES; i++) { for (i = 0; i < ALL_POSSIBLE_SUBFEATURES; i++) {
if (all_subfeatures[i].name) { if (!all_subfeatures[i].name)
dyn_subfeatures[fnum] = all_subfeatures[i]; continue;
if (i >= MAX_SENSORS_PER_TYPE * MAX_SUBFEATURES * 6 ||
i / (MAX_SUBFEATURES * 2) != prev_slot) {
fnum++; fnum++;
prev_slot = i / (MAX_SUBFEATURES * 2);
} }
} }
/* Number the subfeatures linearly, so that subfeature number N is at dyn_subfeatures = calloc(sfnum, sizeof(sensors_subfeature));
position N in the array. This allows for O(1) look-ups. */ dyn_features = calloc(fnum, sizeof(sensors_feature));
for (i = 0; i < fnum; i++) { if (!dyn_subfeatures || !dyn_features)
int j; sensors_fatal_error(__FUNCTION__, "Out of memory");
dyn_subfeatures[i].number = i; /* Copy from the sparse array to the compact array */
if (dyn_subfeatures[i].mapping == SENSORS_NO_MAPPING) { sfnum = 0;
/* Main feature, set the mapping field of all its fnum = -1;
subfeatures */ prev_slot = -1;
for (j = i + 1; j < fnum && for (i = 0; i < ALL_POSSIBLE_SUBFEATURES; i++) {
dyn_subfeatures[j].mapping != SENSORS_NO_MAPPING; if (!all_subfeatures[i].name)
j++) continue;
dyn_subfeatures[j].mapping = i;
/* 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 = dyn_subfeatures;
chip->subfeature_count = fnum; chip->subfeature_count = sfnum;
/* 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->feature = dyn_features; chip->feature = dyn_features;
chip->feature_count = fnum; chip->feature_count = ++fnum;
exit_free: exit_free:
free(all_subfeatures); free(all_subfeatures);
@@ -544,19 +547,11 @@ int sensors_read_sysfs_attr(const sensors_chip_name *name, int subfeat_nr,
const sensors_subfeature *subfeature; const sensors_subfeature *subfeature;
char n[NAME_MAX]; char n[NAME_MAX];
FILE *f; FILE *f;
const char *suffix = "";
if (!(subfeature = sensors_lookup_subfeature_nr(name, subfeat_nr))) if (!(subfeature = sensors_lookup_subfeature_nr(name, subfeat_nr)))
return -SENSORS_ERR_NO_ENTRY; return -SENSORS_ERR_NO_ENTRY;
/* REVISIT: this is a ugly hack */ snprintf(n, NAME_MAX, "%s/%s", name->path, subfeature->name);
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);
if ((f = fopen(n, "r"))) { if ((f = fopen(n, "r"))) {
int res = fscanf(f, "%lf", value); int res = fscanf(f, "%lf", value);
fclose(f); fclose(f);
@@ -575,19 +570,11 @@ int sensors_write_sysfs_attr(const sensors_chip_name *name, int subfeat_nr,
const sensors_subfeature *subfeature; const sensors_subfeature *subfeature;
char n[NAME_MAX]; char n[NAME_MAX];
FILE *f; FILE *f;
const char *suffix = "";
if (!(subfeature = sensors_lookup_subfeature_nr(name, subfeat_nr))) if (!(subfeature = sensors_lookup_subfeature_nr(name, subfeat_nr)))
return -SENSORS_ERR_NO_ENTRY; return -SENSORS_ERR_NO_ENTRY;
/* REVISIT: this is a ugly hack */ snprintf(n, NAME_MAX, "%s/%s", name->path, subfeature->name);
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);
if ((f = fopen(n, "w"))) { if ((f = fopen(n, "w"))) {
value *= get_type_scaling(subfeature->type); value *= get_type_scaling(subfeature->type);
fprintf(f, "%d", (int) value); fprintf(f, "%d", (int) value);

View File

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

View File

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