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

Revision 4643, 11.7 KB (checked in by khali, 6 years ago)

The way we build the feature lists guarantees that subfeatures always
immediately follow their main feature. This makes it possible to simplify
sensors_get_all_features() quite a bit. We no longer need to maintain
separate pointers for the last main feature and the last subfeature,
we can simply walk the list linearly.

Note that I am still not entirely happy with this API. It was obviously
designed for debugging purposes (sensors -u) and without performance
concernes nor interface cleanliness in mind. I believe that we want to
tag main features and subfeatures as such, and let the application ask
specifically for the list of main features, and for each feature, for
its list of subfeatures (i.e. two functions instead of one.)

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,
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)) &&
47      iter->mapping == feature->number) {
48    int indx;
49   
50    indx = iter->type - first_val - 1;
51    if (indx < 0 || indx >= size) {
52      printf("ERROR: Bug in sensors: index out of bound");
53      return;
54    }
55   
56    if (get_feature_value(name, iter, &feature_vals[indx]))
57      printf("ERROR: Can't get %s data!\n", iter->name);
58   
59    has_features[indx] = 1;
60  }
61}
62
63static int sensors_get_label_size(const sensors_chip_name *name)
64{
65  int i, valid;
66  const sensors_feature_data *iter;
67  char *label;
68  unsigned int max_size = 11; /* Initialised to 11 as minumum label-width */
69
70  i = 0;
71  while((iter = sensors_get_all_features(*name, &i))) {
72    if (!sensors_get_label_and_valid(*name, iter->number, &label, &valid) &&
73        valid && strlen(label) > max_size)
74      max_size = strlen(label);
75    free(label);
76  }
77  return max_size + 1;
78}
79
80extern int fahrenheit;
81extern char degstr[5];
82
83static inline float deg_ctof(float cel)
84{
85   return ( cel * ( 9.0F / 5.0F ) + 32.0F );
86}
87
88#define TEMP_FEATURE(x) has_features[x - SENSORS_FEATURE_TEMP - 1]
89#define TEMP_FEATURE_VAL(x) feature_vals[x - SENSORS_FEATURE_TEMP - 1]
90static void print_generic_chip_temp(const sensors_chip_name *name, 
91                                    const sensors_feature_data *feature,
92                                    int i, int label_size)
93{
94  double val, max, min;
95  char *label;
96  int valid, type;
97  const int size = SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP;
98  short has_features[SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP] = {0, };
99  double feature_vals[SENSORS_FEATURE_TEMP_SENS - SENSORS_FEATURE_TEMP] = {0.0, };
100 
101  if (sensors_get_label_and_valid(*name, feature->number, &label, &valid)) {
102    free(label);
103    printf("ERROR: Can't get temperature data!\n");
104    return;
105  } else if (!valid) {
106    free(label);
107    return; /* ignored */
108  }
109 
110  if (get_feature_value(name, feature, &val)) {
111    printf("ERROR: Can't get %s data!\n", label);
112    free(label);
113    return;
114  }
115 
116  sensors_get_available_features(name, feature, i, has_features,
117      feature_vals, size, SENSORS_FEATURE_TEMP);
118 
119  if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX)) {
120    max = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX);
121   
122    if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MIN)) {
123      min = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MIN);
124      type = MINMAX;
125    } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX_HYST)) {
126      min = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX_HYST);
127      type = HYST;
128    } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
129      min = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT);
130      type = CRIT;
131    } else {
132      min = 0;
133      type = MAXONLY;
134    }
135  } else {
136    min = max = 0;
137    type = SINGLE;
138  }
139 
140  if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_FAULT) &&
141      TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_FAULT))
142    val = HUGE_VAL;
143 
144  print_label(label, label_size);
145  free(label);
146 
147  print_temp_info(val, max, min, type, 1, 1);
148 
149  /* ALARM features */
150  if ((TEMP_FEATURE(SENSORS_FEATURE_TEMP_ALARM) && 
151       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_ALARM) > 0.5)
152   || (type == MINMAX &&
153       TEMP_FEATURE(SENSORS_FEATURE_TEMP_MIN_ALARM) && 
154       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MIN_ALARM) > 0.5)
155   || (type == MINMAX &&
156       TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX_ALARM) && 
157       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX_ALARM) > 0.5)
158   || (type == CRIT &&
159       TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) && 
160       TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM) > 0.5)) {
161    printf("ALARM  ");
162  }
163 
164  if (type != CRIT && TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
165    if (fahrenheit) {
166      TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT) = deg_ctof(
167        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT));
168      TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST) = deg_ctof(
169        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST));
170    }
171   
172    if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_HYST))
173      printf("\n%*s(crit = %+5.1f%s, hyst = %+5.1f%s)  ", label_size + 10, "", 
174        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT), degstr,
175        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST), degstr);
176    else
177      printf("\n%*s(crit = %+5.1f%s)  ", label_size + 10, "", 
178        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT), degstr);
179
180    if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) &&
181        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM)) {
182      printf("ALARM  ");
183    }
184  }       
185
186  /* print out temperature sensor info */
187  if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_SENS)) {
188    int sens = (int)TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_SENS);
189   
190    /* older kernels / drivers sometimes report a beta value for thermistors */
191    if (sens > 1000) 
192      sens = 4;
193   
194    printf("sensor = %s", sens == 0 ? "disabled" :
195                          sens == 1 ? "diode" :
196                          sens == 2 ? "transistor" :
197                          sens == 3 ? "thermal diode" :
198                          sens == 4 ? "thermistor" :
199                          sens == 5 ? "AMD AMDSI" :
200                          sens == 6 ? "Intel PECI" :
201                          "unknown");
202  }
203  printf("\n");
204}
205
206#define IN_FEATURE(x) has_features[x - SENSORS_FEATURE_IN - 1]
207#define IN_FEATURE_VAL(x) feature_vals[x - SENSORS_FEATURE_IN - 1]
208static void print_generic_chip_in(const sensors_chip_name *name, 
209                                  const sensors_feature_data *feature,
210                                  int i, int label_size)
211{
212  const int size = SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN;
213  int valid;
214  short has_features[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0, };
215  double feature_vals[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = {0.0, };
216  double val, alarm_max, alarm_min;
217  char *label;
218 
219  if (sensors_get_label_and_valid(*name, feature->number, &label, &valid)) {
220    free(label);
221    printf("ERROR: Can't get in data!\n");
222    return;
223  } else if (!valid) {
224    free(label);
225    return; /* ignored */
226  }
227 
228  if (get_feature_value(name, feature, &val)) {
229    printf("ERROR: Can't get %s data!\n", label);
230    free(label);
231    return;
232  }
233 
234  sensors_get_available_features(name, feature, i, 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 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, 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, label_size;
336 
337  label_size = sensors_get_label_size(name);
338 
339  i = 0;
340  while((feature = sensors_get_all_features(*name, &i))) {
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, label_size); break;
347      case SENSORS_FEATURE_IN:
348        print_generic_chip_in(name, feature, i, label_size); break;
349      case SENSORS_FEATURE_FAN:
350        print_generic_chip_fan(name, feature, i, 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.