root/lm-sensors/branches/lm-sensors-3.0.0/prog/sensors/chips.c @ 4822

Revision 4822, 12.7 KB (checked in by khali, 6 years ago)

Better error handling when a feature value can't be read.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    chips.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 <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "main.h"
27#include "chips.h"
28#include "lib/sensors.h"
29#include "lib/error.h"
30
31void print_chip_raw(const sensors_chip_name *name)
32{
33        int a;
34        const sensors_feature_data *data;
35        char *label;
36        double val;
37
38        a = 0;
39        while ((data = sensors_get_all_features(name, &a))) {
40                if (!(label = sensors_get_label(name, data->number))) {
41                        printf("ERROR: Can't get feature `%s' label!\n",
42                               data->name);
43                        continue;
44                }
45                if (data->flags & SENSORS_MODE_R) {
46                        if (sensors_get_value(name, data->number, &val))
47                                printf("ERROR: Can't get feature `%s' data!\n",
48                                       data->name);
49                        else if (data->mapping != SENSORS_NO_MAPPING)
50                                printf("  %s: %.2f\n", label, val);
51                        else
52                                printf("%s: %.2f (%s)\n", label, val,
53                                       data->name);
54                } else
55                        printf("(%s)\n", label);
56                free(label);
57        }
58}
59
60static inline double deg_ctof(double cel)
61{
62        return cel * (9.0F / 5.0F) + 32.0F;
63}
64
65static void print_label(const char *label, int space)
66{
67        int len = strlen(label)+1;
68        printf("%s:%*s", label, space - len, "");
69}
70
71static void sensors_get_available_features(const sensors_chip_name *name,
72                                           const sensors_feature_data *feature,
73                                           int i, short *has_features,
74                                           double *feature_vals, int size,
75                                           int first_val)
76{
77        const sensors_feature_data *iter;
78
79        while ((iter = sensors_get_all_features(name, &i)) &&
80               iter->mapping == feature->number) {
81                int indx, err;
82
83                indx = iter->type - first_val - 1;
84                if (indx < 0 || indx >= size)
85                        /* New feature in libsensors? Ignore. */
86                        continue;
87
88                err = sensors_get_value(name, iter->number, &feature_vals[indx]);
89                if (err) {
90                        printf("ERROR: Can't get %s data: %s\n", iter->name,
91                               sensors_strerror(err));
92                        continue;
93                }
94
95                has_features[indx] = 1;
96        }
97}
98
99static int sensors_get_label_size(const sensors_chip_name *name)
100{
101        int i;
102        const sensors_feature_data *iter;
103        char *label;
104        unsigned int max_size = 11;     /* 11 as minumum label width */
105
106        i = 0;
107        while ((iter = sensors_get_all_features(name, &i))) {
108                if (iter->mapping != SENSORS_NO_MAPPING)
109                        continue;
110                if ((label = sensors_get_label(name, iter->number)) &&
111                    strlen(label) > max_size)
112                        max_size = strlen(label);
113                free(label);
114        }
115        return max_size + 1;
116}
117
118static void print_temp_limits(double limit1, double limit2,
119                              const char *name1, const char *name2, int alarm)
120{
121        if (fahrenheit) {
122                limit1 = deg_ctof(limit1);
123                limit2 = deg_ctof(limit2);
124        }
125
126        if (name2) {
127                printf("(%-4s = %+5.1f%s, %-4s = %+5.1f%s)  ",
128                       name1, limit1, degstr,
129                       name2, limit2, degstr);
130        } else if (name1) {
131                printf("(%-4s = %+5.1f%s)                  ",
132                       name1, limit1, degstr);
133        } else {
134                printf("                                  ");
135        }
136
137        if (alarm)
138                printf("ALARM  ");
139}
140
141#define TEMP_FEATURE(x)         has_features[x - SENSORS_FEATURE_TEMP - 1]
142#define TEMP_FEATURE_VAL(x)     feature_vals[x - SENSORS_FEATURE_TEMP - 1]
143static void print_chip_temp(const sensors_chip_name *name,
144                            const sensors_feature_data *feature, int i,
145                            int label_size)
146{
147        double val, limit1, limit2;
148        const char *s1, *s2;
149        int alarm, crit_displayed = 0;
150        char *label;
151        const int size = SENSORS_FEATURE_TEMP_TYPE - SENSORS_FEATURE_TEMP;
152        short has_features[SENSORS_FEATURE_TEMP_TYPE - SENSORS_FEATURE_TEMP] = { 0, };
153        double feature_vals[SENSORS_FEATURE_TEMP_TYPE - SENSORS_FEATURE_TEMP] = { 0.0, };
154
155        if (!(label = sensors_get_label(name, feature->number))) {
156                printf("ERROR: Can't get temperature label!\n");
157                return;
158        }
159
160        if (sensors_get_value(name, feature->number, &val)) {
161                printf("ERROR: Can't get %s data!\n", label);
162                free(label);
163                return;
164        }
165
166        sensors_get_available_features(name, feature, i, has_features,
167                                       feature_vals, size,
168                                       SENSORS_FEATURE_TEMP);
169
170        alarm = TEMP_FEATURE(SENSORS_FEATURE_TEMP_ALARM) &&
171                TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_ALARM);
172        if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX)) {
173                if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX_ALARM) &&
174                    TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX_ALARM))
175                        alarm |= 1;
176
177                if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MIN)) {
178                        limit1 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MIN);
179                        s1 = "low";
180                        limit2 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX);
181                        s2 = "high";
182
183                        if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MIN_ALARM) &&
184                            TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MIN_ALARM))
185                                alarm |= 1;
186                } else {
187                        limit1 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX);
188                        s1 = "high";
189
190                        if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_MAX_HYST)) {
191                                limit2 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_MAX_HYST);
192                                s2 = "hyst";
193                        } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
194                                limit2 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT);
195                                s2 = "crit";
196
197                                if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) &&
198                                    TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM))
199                                        alarm |= 1;
200                                crit_displayed = 1;
201                        } else {
202                                limit2 = 0;
203                                s2 = NULL;
204                        }
205                }
206        } else if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
207                limit1 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT);
208                s1 = "crit";
209
210                if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_HYST)) {
211                        limit2 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST);
212                        s2 = "hyst";
213                } else {
214                        limit2 = 0;
215                        s2 = NULL;
216                }
217
218                if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) &&
219                    TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM))
220                        alarm |= 1;
221                crit_displayed = 1;
222        } else {
223                limit1 = limit2 = 0;
224                s1 = s2 = NULL;
225        }
226
227        print_label(label, label_size);
228        free(label);
229
230        if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_FAULT) &&
231            TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_FAULT)) {
232                printf("   FAULT  ");
233        } else {
234                if (fahrenheit)
235                        val = deg_ctof(val);
236                printf("%+6.1f%s  ", val, degstr);
237        }
238        print_temp_limits(limit1, limit2, s1, s2, alarm);
239
240        if (!crit_displayed && TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT)) {
241                limit1 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT);
242                s1 = "crit";
243
244                if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_HYST)) {
245                        limit2 = TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_HYST);
246                        s2 = "hyst";
247                } else {
248                        limit2 = 0;
249                        s2 = NULL;
250                }
251
252                alarm = TEMP_FEATURE(SENSORS_FEATURE_TEMP_CRIT_ALARM) &&
253                        TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_CRIT_ALARM);
254
255                printf("\n%*s", label_size + 10, "");
256                print_temp_limits(limit1, limit2, s1, s2, alarm);
257        }
258
259        /* print out temperature sensor info */
260        if (TEMP_FEATURE(SENSORS_FEATURE_TEMP_TYPE)) {
261                int sens = (int)TEMP_FEATURE_VAL(SENSORS_FEATURE_TEMP_TYPE);
262
263                /* older kernels / drivers sometimes report a beta value for
264                   thermistors */
265                if (sens > 1000)
266                        sens = 4;
267
268                printf("sensor = %s", sens == 0 ? "disabled" :
269                       sens == 1 ? "diode" :
270                       sens == 2 ? "transistor" :
271                       sens == 3 ? "thermal diode" :
272                       sens == 4 ? "thermistor" :
273                       sens == 5 ? "AMD AMDSI" :
274                       sens == 6 ? "Intel PECI" : "unknown");
275        }
276        printf("\n");
277}
278
279#define IN_FEATURE(x)           has_features[x - SENSORS_FEATURE_IN - 1]
280#define IN_FEATURE_VAL(x)       feature_vals[x - SENSORS_FEATURE_IN - 1]
281static void print_chip_in(const sensors_chip_name *name,
282                          const sensors_feature_data *feature, int i,
283                          int label_size)
284{
285        const int size = SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN;
286        short has_features[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = { 0, };
287        double feature_vals[SENSORS_FEATURE_IN_MAX_ALARM - SENSORS_FEATURE_IN] = { 0.0, };
288        double val, alarm_max, alarm_min;
289        char *label;
290
291        if (!(label = sensors_get_label(name, feature->number))) {
292                printf("ERROR: Can't get in label!\n");
293                return;
294        }
295
296        if (sensors_get_value(name, feature->number, &val)) {
297                printf("ERROR: Can't get %s data!\n", label);
298                free(label);
299                return;
300        }
301
302        sensors_get_available_features(name, feature, i, has_features,
303                                       feature_vals, size, SENSORS_FEATURE_IN);
304
305        print_label(label, label_size);
306        free(label);
307        printf("%+6.2f V", val);
308
309        if (IN_FEATURE(SENSORS_FEATURE_IN_MIN) &&
310            IN_FEATURE(SENSORS_FEATURE_IN_MAX))
311                printf("  (min = %+6.2f V, max = %+6.2f V)",
312                       IN_FEATURE_VAL(SENSORS_FEATURE_IN_MIN),
313                       IN_FEATURE_VAL(SENSORS_FEATURE_IN_MAX));
314        else if (IN_FEATURE(SENSORS_FEATURE_IN_MIN))
315                printf("  (min = %+6.2f V)",
316                       IN_FEATURE_VAL(SENSORS_FEATURE_IN_MIN));
317        else if (IN_FEATURE(SENSORS_FEATURE_IN_MAX))
318                printf("  (max = %+6.2f V)",
319                       IN_FEATURE_VAL(SENSORS_FEATURE_IN_MAX));
320
321        if (IN_FEATURE(SENSORS_FEATURE_IN_MAX_ALARM) ||
322            IN_FEATURE(SENSORS_FEATURE_IN_MIN_ALARM)) {
323                alarm_max = IN_FEATURE_VAL(SENSORS_FEATURE_IN_MAX_ALARM);
324                alarm_min = IN_FEATURE_VAL(SENSORS_FEATURE_IN_MIN_ALARM);
325
326                if (alarm_min || alarm_max) {
327                        printf(" ALARM (");
328
329                        if (alarm_min)
330                                printf("MIN");
331                        if (alarm_max)
332                                printf("%sMAX", (alarm_min) ? ", " : "");
333
334                        printf(")");
335                }
336        } else if (IN_FEATURE(SENSORS_FEATURE_IN_ALARM)) {
337                printf("   %s",
338                IN_FEATURE_VAL(SENSORS_FEATURE_IN_ALARM) ? "ALARM" : "");
339        }
340
341        printf("\n");
342}
343
344#define FAN_FEATURE(x)          has_features[x - SENSORS_FEATURE_FAN - 1]
345#define FAN_FEATURE_VAL(x)      feature_vals[x - SENSORS_FEATURE_FAN - 1]
346static void print_chip_fan(const sensors_chip_name *name,
347                           const sensors_feature_data *feature, int i,
348                           int label_size)
349{
350        char *label;
351        const int size = SENSORS_FEATURE_FAN_DIV - SENSORS_FEATURE_FAN;
352        short has_features[SENSORS_FEATURE_FAN_DIV - SENSORS_FEATURE_FAN] = { 0, };
353        double feature_vals[SENSORS_FEATURE_FAN_DIV - SENSORS_FEATURE_FAN] = { 0.0, };
354        double val;
355
356        if (!(label = sensors_get_label(name, feature->number))) {
357                printf("ERROR: Can't get fan label!\n");
358                return;
359        }
360
361        if (sensors_get_value(name, feature->number, &val)) {
362                printf("ERROR: Can't get %s data!\n", label);
363                free(label);
364                return;
365        }
366
367        print_label(label, label_size);
368        free(label);
369
370        sensors_get_available_features(name, feature, i, has_features,
371                                       feature_vals, size, SENSORS_FEATURE_FAN);
372
373        if (FAN_FEATURE(SENSORS_FEATURE_FAN_FAULT) &&
374            FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_FAULT))
375                printf("   FAULT");
376        else
377                printf("%4.0f RPM", val);
378
379        if (FAN_FEATURE(SENSORS_FEATURE_FAN_MIN) &&
380            FAN_FEATURE(SENSORS_FEATURE_FAN_DIV))
381                printf("  (min = %4.0f RPM, div = %1.0f)",
382                       FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_MIN),
383                       FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_DIV));
384        else if (FAN_FEATURE(SENSORS_FEATURE_FAN_MIN))
385                printf("  (min = %4.0f RPM)",
386                       FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_MIN));
387        else if (FAN_FEATURE(SENSORS_FEATURE_FAN_DIV))
388                printf("  (div = %1.0f)",
389                       FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_DIV));
390
391        if (FAN_FEATURE(SENSORS_FEATURE_FAN_ALARM) &&
392            FAN_FEATURE_VAL(SENSORS_FEATURE_FAN_ALARM)) {
393                printf("  ALARM");
394        }
395
396        printf("\n");
397}
398
399static void print_chip_vid(const sensors_chip_name *name, int f_vid,
400                           int label_size)
401{
402        char *label;
403        double vid;
404
405        if ((label = sensors_get_label(name, f_vid))
406         && !sensors_get_value(name, f_vid, &vid)) {
407                print_label(label, label_size);
408                printf("%+6.3f V\n", vid);
409        }
410        free(label);
411}
412
413static void print_chip_beep_enable(const sensors_chip_name *name, int f_beep,
414                                   int label_size)
415{
416        char *label;
417        double beep_enable;
418
419        if ((label = sensors_get_label(name, f_beep))
420         && !sensors_get_value(name, f_beep, &beep_enable)) {
421                print_label(label, label_size);
422                printf("%s\n", beep_enable ? "enabled" : "disabled");
423        }
424        free(label);
425}
426
427void print_chip(const sensors_chip_name *name)
428{
429        const sensors_feature_data *feature;
430        int i, label_size;
431
432        label_size = sensors_get_label_size(name);
433
434        i = 0;
435        while ((feature = sensors_get_all_features(name, &i))) {
436                if (feature->mapping != SENSORS_NO_MAPPING)
437                        continue;
438
439                switch (feature->type) {
440                case SENSORS_FEATURE_TEMP:
441                        print_chip_temp(name, feature, i, label_size);
442                        break;
443                case SENSORS_FEATURE_IN:
444                        print_chip_in(name, feature, i, label_size);
445                        break;
446                case SENSORS_FEATURE_FAN:
447                        print_chip_fan(name, feature, i, label_size);
448                        break;
449                case SENSORS_FEATURE_VID:
450                        print_chip_vid(name, feature->number, label_size);
451                        break;
452                case SENSORS_FEATURE_BEEP_ENABLE:
453                        print_chip_beep_enable(name, feature->number,
454                                               label_size);
455                        break;
456                default:
457                        continue;
458                }
459        }
460}
Note: See TracBrowser for help on using the browser.