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

Revision 4801, 12.6 KB (checked in by khali, 7 years ago)

Fix fan fault handling. We were testing for fan fault before actually
retrieving the fan features, so faults could not be detected. Swapping
the instructions fixes it.

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