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

Revision 4838, 13.0 KB (checked in by khali, 6 years ago)

Introduce a separate type for main features. Make subfeatures map to
the real main feature rather than the first subfeature.

  • 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, b;
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                        printf("ERROR: Can't get feature label!\n");
43                        continue;
44                }
45                printf("%s:\n", label);
46                free(label);
47
48                b = 0;
49                while ((sub = sensors_get_all_subfeatures(name, feature, &b))) {
50                        if (sub->flags & SENSORS_MODE_R) {
51                                if (sensors_get_value(name, sub->number, &val))
52                                        printf("ERROR: Can't get feature `%s' "
53                                               "data!\n", sub->name);
54                                else
55                                        printf("  %s: %.2f\n", sub->name, val);
56                        } else
57                                printf("(%s)\n", label);
58                }
59        }
60}
61
62static inline double deg_ctof(double cel)
63{
64        return cel * (9.0F / 5.0F) + 32.0F;
65}
66
67static void print_label(const char *label, int space)
68{
69        int len = strlen(label)+1;
70        printf("%s:%*s", label, space - len, "");
71}
72
73static void sensors_get_available_features(const sensors_chip_name *name,
74                                           const sensors_feature *feature,
75                                           short *has_features,
76                                           double *feature_vals, int size,
77                                           int first_val)
78{
79        const sensors_subfeature *iter;
80        int i = 0;
81
82        while ((iter = sensors_get_all_subfeatures(name, feature, &i))) {
83                int indx, err;
84
85                indx = iter->type - first_val;
86                if (indx < 0 || indx >= size)
87                        /* New feature in libsensors? Ignore. */
88                        continue;
89
90                err = sensors_get_value(name, iter->number, &feature_vals[indx]);
91                if (err) {
92                        printf("ERROR: Can't get %s data: %s\n", iter->name,
93                               sensors_strerror(err));
94                        continue;
95                }
96
97                has_features[indx] = 1;
98        }
99}
100
101static int sensors_get_label_size(const sensors_chip_name *name)
102{
103        int i;
104        const sensors_feature *iter;
105        char *label;
106        unsigned int max_size = 11;     /* 11 as minumum label width */
107
108        i = 0;
109        while ((iter = sensors_get_features(name, &i))) {
110                if ((label = sensors_get_label(name, iter)) &&
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_SUBFEATURE_TEMP_INPUT]
142#define TEMP_FEATURE_VAL(x)     feature_vals[x - SENSORS_SUBFEATURE_TEMP_INPUT]
143static void print_chip_temp(const sensors_chip_name *name,
144                            const sensors_feature *feature,
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_SUBFEATURE_TEMP_TYPE - SENSORS_SUBFEATURE_TEMP_INPUT + 1;
152        short has_features[SENSORS_SUBFEATURE_TEMP_TYPE - SENSORS_SUBFEATURE_TEMP_INPUT + 1] = { 0, };
153        double feature_vals[SENSORS_SUBFEATURE_TEMP_TYPE - SENSORS_SUBFEATURE_TEMP_INPUT + 1] = { 0.0, };
154
155        if (!(label = sensors_get_label(name, feature))) {
156                printf("ERROR: Can't get temperature label!\n");
157                return;
158        }
159
160        sensors_get_available_features(name, feature, has_features,
161                                       feature_vals, size,
162                                       SENSORS_SUBFEATURE_TEMP_INPUT);
163        val = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_INPUT);
164
165        alarm = TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_ALARM) &&
166                TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_ALARM);
167        if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX)) {
168                if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX_ALARM) &&
169                    TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX_ALARM))
170                        alarm |= 1;
171
172                if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MIN)) {
173                        limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MIN);
174                        s1 = "low";
175                        limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX);
176                        s2 = "high";
177
178                        if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MIN_ALARM) &&
179                            TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MIN_ALARM))
180                                alarm |= 1;
181                } else {
182                        limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX);
183                        s1 = "high";
184
185                        if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_MAX_HYST)) {
186                                limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_MAX_HYST);
187                                s2 = "hyst";
188                        } else if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT)) {
189                                limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT);
190                                s2 = "crit";
191
192                                if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM) &&
193                                    TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_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_SUBFEATURE_TEMP_CRIT)) {
202                limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT);
203                s1 = "crit";
204
205                if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_HYST)) {
206                        limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_HYST);
207                        s2 = "hyst";
208                } else {
209                        limit2 = 0;
210                        s2 = NULL;
211                }
212
213                if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM) &&
214                    TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_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_SUBFEATURE_TEMP_FAULT) &&
226            TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_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_SUBFEATURE_TEMP_CRIT)) {
236                limit1 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT);
237                s1 = "crit";
238
239                if (TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_HYST)) {
240                        limit2 = TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_TEMP_CRIT_HYST);
241                        s2 = "hyst";
242                } else {
243                        limit2 = 0;
244                        s2 = NULL;
245                }
246
247                alarm = TEMP_FEATURE(SENSORS_SUBFEATURE_TEMP_CRIT_ALARM) &&
248                        TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_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_SUBFEATURE_TEMP_TYPE)) {
256                int sens = (int)TEMP_FEATURE_VAL(SENSORS_SUBFEATURE_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_SUBFEATURE_IN_INPUT]
275#define IN_FEATURE_VAL(x)       feature_vals[x - SENSORS_SUBFEATURE_IN_INPUT]
276static void print_chip_in(const sensors_chip_name *name,
277                          const sensors_feature *feature,
278                          int label_size)
279{
280        const int size = SENSORS_SUBFEATURE_IN_MAX_ALARM - SENSORS_SUBFEATURE_IN_INPUT + 1;
281        short has_features[SENSORS_SUBFEATURE_IN_MAX_ALARM - SENSORS_SUBFEATURE_IN_INPUT + 1] = { 0, };
282        double feature_vals[SENSORS_SUBFEATURE_IN_MAX_ALARM - SENSORS_SUBFEATURE_IN_INPUT + 1] = { 0.0, };
283        double val, alarm_max, alarm_min;
284        char *label;
285
286        if (!(label = sensors_get_label(name, feature))) {
287                printf("ERROR: Can't get in label!\n");
288                return;
289        }
290
291        sensors_get_available_features(name, feature, has_features,
292                                       feature_vals, size,
293                                       SENSORS_SUBFEATURE_IN_INPUT);
294        val = IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_INPUT);
295
296        print_label(label, label_size);
297        free(label);
298        printf("%+6.2f V", val);
299
300        if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN) &&
301            IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX))
302                printf("  (min = %+6.2f V, max = %+6.2f V)",
303                       IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MIN),
304                       IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MAX));
305        else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN))
306                printf("  (min = %+6.2f V)",
307                       IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MIN));
308        else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX))
309                printf("  (max = %+6.2f V)",
310                       IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MAX));
311
312        if (IN_FEATURE(SENSORS_SUBFEATURE_IN_MAX_ALARM) ||
313            IN_FEATURE(SENSORS_SUBFEATURE_IN_MIN_ALARM)) {
314                alarm_max = IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MAX_ALARM);
315                alarm_min = IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_MIN_ALARM);
316
317                if (alarm_min || alarm_max) {
318                        printf(" ALARM (");
319
320                        if (alarm_min)
321                                printf("MIN");
322                        if (alarm_max)
323                                printf("%sMAX", (alarm_min) ? ", " : "");
324
325                        printf(")");
326                }
327        } else if (IN_FEATURE(SENSORS_SUBFEATURE_IN_ALARM)) {
328                printf("   %s",
329                IN_FEATURE_VAL(SENSORS_SUBFEATURE_IN_ALARM) ? "ALARM" : "");
330        }
331
332        printf("\n");
333}
334
335#define FAN_FEATURE(x)          has_features[x - SENSORS_SUBFEATURE_FAN_INPUT]
336#define FAN_FEATURE_VAL(x)      feature_vals[x - SENSORS_SUBFEATURE_FAN_INPUT]
337static void print_chip_fan(const sensors_chip_name *name,
338                           const sensors_feature *feature,
339                           int label_size)
340{
341        char *label;
342        const int size = SENSORS_SUBFEATURE_FAN_DIV - SENSORS_SUBFEATURE_FAN_INPUT + 1;
343        short has_features[SENSORS_SUBFEATURE_FAN_DIV - SENSORS_SUBFEATURE_FAN_INPUT + 1] = { 0, };
344        double feature_vals[SENSORS_SUBFEATURE_FAN_DIV - SENSORS_SUBFEATURE_FAN_INPUT + 1] = { 0.0, };
345        double val;
346
347        if (!(label = sensors_get_label(name, feature))) {
348                printf("ERROR: Can't get fan label!\n");
349                return;
350        }
351
352        print_label(label, label_size);
353        free(label);
354
355        sensors_get_available_features(name, feature, has_features,
356                                       feature_vals, size,
357                                       SENSORS_SUBFEATURE_FAN_INPUT);
358        val = FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_INPUT);
359
360        if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_FAULT) &&
361            FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_FAULT))
362                printf("   FAULT");
363        else
364                printf("%4.0f RPM", val);
365
366        if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_MIN) &&
367            FAN_FEATURE(SENSORS_SUBFEATURE_FAN_DIV))
368                printf("  (min = %4.0f RPM, div = %1.0f)",
369                       FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_MIN),
370                       FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_DIV));
371        else if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_MIN))
372                printf("  (min = %4.0f RPM)",
373                       FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_MIN));
374        else if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_DIV))
375                printf("  (div = %1.0f)",
376                       FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_DIV));
377
378        if (FAN_FEATURE(SENSORS_SUBFEATURE_FAN_ALARM) &&
379            FAN_FEATURE_VAL(SENSORS_SUBFEATURE_FAN_ALARM)) {
380                printf("  ALARM");
381        }
382
383        printf("\n");
384}
385
386static void print_chip_vid(const sensors_chip_name *name,
387                           const sensors_feature *feature,
388                           int label_size)
389{
390        char *label;
391        const sensors_subfeature *subfeature;
392        double vid;
393        int i = 0;
394
395        subfeature = sensors_get_all_subfeatures(name, feature, &i);
396        if (!subfeature)
397                return;
398
399        if ((label = sensors_get_label(name, feature))
400         && !sensors_get_value(name, subfeature->number, &vid)) {
401                print_label(label, label_size);
402                printf("%+6.3f V\n", vid);
403        }
404        free(label);
405}
406
407static void print_chip_beep_enable(const sensors_chip_name *name,
408                                   const sensors_feature *feature,
409                                   int label_size)
410{
411        char *label;
412        const sensors_subfeature *subfeature;
413        double beep_enable;
414        int i = 0;
415
416        subfeature = sensors_get_all_subfeatures(name, feature, &i);
417        if (!subfeature)
418                return;
419
420        if ((label = sensors_get_label(name, feature))
421         && !sensors_get_value(name, subfeature->number, &beep_enable)) {
422                print_label(label, label_size);
423                printf("%s\n", beep_enable ? "enabled" : "disabled");
424        }
425        free(label);
426}
427
428void print_chip(const sensors_chip_name *name)
429{
430        const sensors_feature *feature;
431        int i, label_size;
432
433        label_size = sensors_get_label_size(name);
434
435        i = 0;
436        while ((feature = sensors_get_features(name, &i))) {
437                switch (feature->type) {
438                case SENSORS_FEATURE_TEMP:
439                        print_chip_temp(name, feature, label_size);
440                        break;
441                case SENSORS_FEATURE_IN:
442                        print_chip_in(name, feature, label_size);
443                        break;
444                case SENSORS_FEATURE_FAN:
445                        print_chip_fan(name, feature, label_size);
446                        break;
447                case SENSORS_FEATURE_VID:
448                        print_chip_vid(name, feature, label_size);
449                        break;
450                case SENSORS_FEATURE_BEEP_ENABLE:
451                        print_chip_beep_enable(name, feature, label_size);
452                        break;
453                default:
454                        continue;
455                }
456        }
457}
Note: See TracBrowser for help on using the browser.