root/lm-sensors/branches/lm-sensors-3.0.0/prog/sensors/chips_generic.c @ 4629

Revision 4629, 11.8 KB (checked in by khali, 6 years ago)

The way we use sensors_feature_get_type() is rather suboptimal. It is
first called during the library initialization to generate the feature
tables. Then it is called again by sensors itself. This is because we
do not store the result the first time. I propose that we add a type
field to struct sensors_feature_data, where libsensors would store
the result of sensors_feature_get_type(). That way, the application
can get the information without calling sensors_feature_get_type()
again.

This change has the following benefits:
* Obviously, a small speed-up.
* sensors_feature_get_type() can be removed from the public interface.

This means that we can turn it into something that fits the
libsensors needs better, allowing for more optimizations (see next
patches.)

Note: the patch looks bigger that it really is, because I had to move
definitions around in sensors.h.

Line 
1/*
2    chips_generic.c - Part of sensors, a user-space program for hardware monitoring
3    Copyright (c) 1998-2003 Frodo Looijaard <frodol@dds.nl>
4                            and Mark D. Studebaker <mdsxyz123@yahoo.com>
5    Copyright (c) 2003-2006 The lm_sensors team
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <stdlib.h>
23#include <string.h>
24#include <math.h>
25
26#include "chips_generic.h"
27#include "chips.h"
28
29static int get_feature_value(const sensors_chip_name *name, 
30                             const sensors_feature_data *feature, 
31                             double *val)
32{
33  return sensors_get_feature(*name, feature->number, val);
34}
35
36static void sensors_get_available_features(const sensors_chip_name *name, 
37                                           const sensors_feature_data *feature, 
38                                           int i, int j, 
39                                           short *has_features, 
40                                           double *feature_vals, 
41                                           int size, 
42                                           int first_val)
43{
44  const sensors_feature_data *iter;
45 
46  while((iter = sensors_get_all_features(*name, &i, &j)) && 
47      iter->mapping != SENSORS_NO_MAPPING &&
48      iter->mapping == feature->number) {
49    int indx;
50   
51    indx = iter->type - first_val - 1;
52    if (indx < 0 || indx >= size) {
53      printf("ERROR: Bug in sensors: index out of bound");
54      return;
55    }
56   
57    if (get_feature_value(name, iter, &feature_vals[indx]))
58      printf("ERROR: Can't get %s data!\n", iter->name);
59   
60    has_features[indx] = 1;
61  }
62}
63
64static int sensors_get_label_size(const sensors_chip_name *name)
65{
66  int i, j, valid;
67  const sensors_feature_data *iter;
68  char *label;
69  unsigned int max_size = 11; /* Initialised to 11 as minumum label-width */
70
71  i = j = 0;
72  while((iter = sensors_get_all_features(*name, &i, &j))) {
73    if (!sensors_get_label_and_valid(*name, iter->number, &label, &valid) &&
74        valid && strlen(label) > max_size)
75      max_size = strlen(label);
76    free(label);
77  }
78  return max_size + 1;
79}
80
81extern int fahrenheit;
82extern char degstr[5];
83
84static inline float deg_ctof(float cel)
85{
86   return ( cel * ( 9.0F / 5.0F ) + 32.0F );
87}
88
89#define TEMP_FEATURE(x) has_features[x - SENSORS_FEATURE_TEMP - 1]
90#define TEMP_FEATURE_VAL(x) feature_vals[x - SENSORS_FEATURE_TEMP - 1]
91static void print_generic_chip_temp(const sensors_chip_name *name, 
92                                    const sensors_feature_data *feature,
93                                    int i, int j, int label_size)
94{
95  double val, max, min;
96  char *label;
97  int valid, type;
98  const int size = SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP;
99  short has_features[SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP] = {0, };
100  double feature_vals[SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP] = {0.0, };
101 
102  if (sensors_get_label_and_valid(*name, feature->number, &label, &valid)) {
103    free(label);
104    printf("ERROR: Can't get temperature data!\n");
105    return;
106  } else if (!valid) {
107    free(label);
108    return; /* ignored */
109  }
110 
111  if (get_feature_value(name, feature, &val)) {
112    free(label);
113    printf("ERROR: Can't get temperature data!\n");
114    return;
115  }
116 
117  sensors_get_available_features(name, feature, i, j, has_features, 
118      feature_vals, size, SENSORS_FEATURE_TEMP);
119 
120  if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX)) {
121    max = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX);
122   
123    if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MIN)) {
124      min = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MIN);
125      type = MINMAX;
126    } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX_HYST)) {
127      min = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX_HYST);
128      type = HYST;
129    } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
130      min = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT);
131      type = CRIT;
132    } else {
133      min = 0;
134      type = MAXONLY;
135    }
136  } else {
137    min = max = 0;
138    type = SINGLE;
139  }
140 
141  if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_FAULT) &&
142      TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_FAULT))
143    val = HUGE_VAL;
144 
145  print_label(label, label_size);
146  free(label);
147 
148  print_temp_info(val, max, min, type, 1, 1);
149 
150  /* ALARM features */
151  if ((TEMP_FEATURE(SENSORS_FEATURE_TEMP_ALARM) && 
152       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_ALARM) > 0.5)
153   || (type == MINMAX &&
154       TEMP_FEATURE(SENSORS_FEATURE_TEMP_MIN_ALARM) && 
155       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MIN_ALARM) > 0.5)
156   || (type == MINMAX &&
157       TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX_ALARM) && 
158       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX_ALARM) > 0.5)
159   || (type == CRIT &&
160       TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) && 
161       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM) > 0.5)) {
162    printf("ALARM  ");
163  }
164 
165  if (type != CRIT && TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
166    if (fahrenheit) {
167      TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT) = deg_ctof(
168        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT));
169      TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST) = deg_ctof(
170        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST));
171    }
172   
173    if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_HYST))
174      printf("\n%*s(crit = %+5.1f%s, hyst = %+5.1f%s)  ", label_size + 10, "", 
175        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT), degstr,
176        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST), degstr);
177    else
178      printf("\n%*s(crit = %+5.1f%s)  ", label_size + 10, "", 
179        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT), degstr);
180
181    if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) &&
182        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM)) {
183      printf("ALARM  ");
184    }
185  }       
186
187  /* print out temperature sensor info */
188  if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_SENS)) {
189    int sens = (int)TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_SENS);
190   
191    /* older kernels / drivers sometimes report a beta value for thermistors */
192    if (sens > 1000) 
193      sens = 4;
194   
195    printf("sensor = %s", sens == 0 ? "disabled" :
196                          sens == 1 ? "diode" :
197                          sens == 2 ? "transistor" :
198                          sens == 3 ? "thermal diode" :
199                          sens == 4 ? "thermistor" :
200                          sens == 5 ? "AMD AMDSI" :
201                          sens == 6 ? "Intel PECI" :
202                          "unknown");
203  }
204  printf("\n");
205}
206
207#define IN_FEATURE(x) has_features[x - SENSORS_FEATURE_IN - 1]
208#define IN_FEATURE_VAL(x) feature_vals[x - SENSORS_FEATURE_IN - 1]
209static void print_generic_chip_in(const sensors_chip_name *name, 
210                                  const sensors_feature_data *feature,
211                                  int i, int j, int label_size)
212{
213  const int size = SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN;
214  int valid;
215  short has_features[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0, };
216  double feature_vals[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0.0, };
217  double val, alarm_max, alarm_min;
218  char *label;
219 
220  if (sensors_get_label_and_valid(*name, feature->number, &label, &valid)) {
221    free(label);
222    printf("ERROR: Can't get in data!\n");
223    return;
224  } else if (!valid) {
225    free(label);
226    return; /* ignored */
227  }
228 
229  if (get_feature_value(name, feature, &val)) {
230    printf("ERROR: Can't get %s data!\n", label);
231    return;
232  }
233 
234  sensors_get_available_features(name, feature, i, j, has_features, feature_vals,
235      size, SENSORS_FEATURE_IN);
236 
237  print_label(label, label_size);
238  free(label);
239  printf("%+6.2f V", val);
240 
241  if (IN_FEATURE(SENSORS_FEATURE_IN_MIN) && IN_FEATURE(SENSORS_FEATURE_IN_MAX))
242    printf("  (min = %+6.2f V, max = %+6.2f V)",
243      IN_FEATURE_VAL(SENSORS_FEATURE_IN_MIN),
244      IN_FEATURE_VAL(SENSORS_FEATURE_IN_MAX));
245  else if (IN_FEATURE(SENSORS_FEATURE_IN_MIN))
246    printf("  (min = %+6.2f V)", IN_FEATURE_VAL(SENSORS_FEATURE_IN_MIN));
247  else if (IN_FEATURE(SENSORS_FEATURE_IN_MAX))
248    printf("  (max = %+6.2f V)", IN_FEATURE_VAL(SENSORS_FEATURE_IN_MAX));
249 
250  if (IN_FEATURE(SENSORS_FEATURE_IN_MAX_ALARM) ||
251      IN_FEATURE(SENSORS_FEATURE_IN_MIN_ALARM)) {
252    alarm_max = IN_FEATURE_VAL(SENSORS_FEATURE_IN_MAX_ALARM);
253    alarm_min = IN_FEATURE_VAL(SENSORS_FEATURE_IN_MIN_ALARM);
254   
255    if (alarm_min || alarm_max) {
256      printf(" ALARM (");
257     
258      if (alarm_min)
259        printf("MIN");
260      if (alarm_max)
261        printf("%sMAX", (alarm_min) ? ", " : "");
262     
263      printf(")");
264    }
265  } else if (IN_FEATURE(SENSORS_FEATURE_IN_ALARM)) {
266    printf("   %s", 
267    IN_FEATURE_VAL(SENSORS_FEATURE_IN_ALARM) ? "ALARM" : "");
268  }
269 
270  printf("\n");
271}
272
273#define FAN_FEATURE(x) has_features[x - SENSORS_FEATURE_FAN - 1]
274#define FAN_FEATURE_VAL(x) feature_vals[x - SENSORS_FEATURE_FAN - 1]
275static void print_generic_chip_fan(const sensors_chip_name *name, 
276                                   const sensors_feature_data *feature,
277                                   int i, int j, int label_size)
278{
279  char *label;
280  int valid;
281  const int size = SENSORS_FEATURE_FAN_DIV - SENSORS_FEATURE_FAN;
282  short has_features[SENSORS_FEATURE_FAN_DIV - SENSORS_FEATURE_FAN] = {0, };
283  double feature_vals[SENSORS_FEATURE_FAN_DIV - SENSORS_FEATURE_FAN] = {0.0, };
284  double val;
285 
286  if (sensors_get_label_and_valid(*name, feature->number, &label, &valid)) {
287    printf("ERROR: Can't get fan data!\n");
288    free(label);
289    return;
290  } else if (!valid) {
291    free(label);
292    return; /* ignored */
293  }
294 
295  if (get_feature_value(name, feature, &val))
296  {
297    printf("ERROR: Can't get %s data!\n", label);
298    free(label);
299    return;
300  }
301 
302  print_label(label, label_size);
303  free(label);
304
305  if (FAN_FEATURE(SENSORS_FEATURE_FAN_FAULT) &&
306      FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_FAULT))
307    printf("   FAULT");
308  else
309    printf("%4.0f RPM", val);
310 
311  sensors_get_available_features(name, feature, i, j, has_features, feature_vals,
312      size, SENSORS_FEATURE_FAN);
313 
314  if (FAN_FEATURE(SENSORS_FEATURE_FAN_MIN) &&
315      FAN_FEATURE(SENSORS_FEATURE_FAN_DIV))
316    printf("  (min = %4.0f RPM, div = %1.0f)",
317      FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_MIN),
318      FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_DIV));
319  else if (FAN_FEATURE(SENSORS_FEATURE_FAN_MIN))
320    printf("  (min = %4.0f RPM)", FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_MIN));
321  else if (FAN_FEATURE(SENSORS_FEATURE_FAN_DIV))
322    printf("  (div = %1.0f)", FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_DIV));
323 
324  if (FAN_FEATURE(SENSORS_FEATURE_FAN_ALARM) && 
325      FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_ALARM)) {
326    printf("  ALARM");
327  }       
328 
329  printf("\n");
330}
331
332void print_generic_chip(const sensors_chip_name *name)
333{
334  const sensors_feature_data *feature;
335  int i,j, label_size;
336 
337  label_size = sensors_get_label_size(name);
338 
339  i = j = 0;
340  while((feature = sensors_get_all_features(*name, &i, &j))) {
341    if (feature->mapping != SENSORS_NO_MAPPING)
342      continue;
343   
344    switch (feature->type) {
345      case SENSORS_FEATURE_TEMP:
346        print_generic_chip_temp(name, feature, i, j, label_size); break;
347      case SENSORS_FEATURE_IN:
348        print_generic_chip_in(name, feature, i, j, label_size); break;
349      case SENSORS_FEATURE_FAN:
350        print_generic_chip_fan(name, feature, i, j, label_size); break;
351      case SENSORS_FEATURE_VID:
352        print_vid_info(name, feature->number, label_size); break;
353      default: continue;
354    }
355  }
356}
Note: See TracBrowser for help on using the browser.