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

Revision 4910, 11.7 KB (checked in by khali, 7 years ago)

sensors: Better handling of the fault flags.

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