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

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

New public library function: sensors_get_subfeature(). Applications can
use it to retrieve a specific subfeature by type. While it is slighly
less efficient than looping over sensors_get_all_subfeatures(), it
often makes the application code much more elegant.

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