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

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

Split sensors_get_all_features() into two distinct functions, one to
get the list of all main features, and one to get the list of all the
subfeatures of a given main feature. This is a more logical interface for
applications to use. The current implementation is admittedly less than
optimal, because the storage structures weren't meant for it, but this
issue can (and will) be addressed later.

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