/*
* Copyright (c) 1999
* Chris D. Faulhaber <jedgar@fxp.org>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY CHRIS D. FAULHABER ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL CHRIS D. FAULHABER BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Portions of this software derived from examples (c) 1998 Takanori Watanabe.
*
* Addition of an output format (-m) suitable for the UCD SNMP Agent
* Kevin Walton, <kevinw@demon.net>, March 2000
*
* $Id: lmmon.c,v 1.31 2000/03/08 17:41:28 jedgar Exp $
*/
#include <curses.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <machine/cpufunc.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SMB
#include <dev/smbus/smb.h>
#endif
#include "lmmon.h"
void
usage()
{
(void)fprintf(stderr, "%s%s\n%s\n",
"lmmon v", LMMON_VERSION,
"usage: lmmon [-hipsvm] [-r delay]");
exit(1);
}
u_char
get_data(int iodev, u_char command, int interface)
{
u_char return_val;
return_val = 0;
#ifdef HAVE_SMB
if (interface == INTERFACE_SMB) {
struct smbcmd cmd;
u_char byte;
byte = 0;
/* Initialize the struct */
bzero(&cmd, sizeof(cmd));
cmd.data.byte_ptr = &byte;
cmd.slave = 0x5a;
cmd.cmd = command;
/* Send the command */
if (ioctl(iodev, SMB_READB, (caddr_t)&cmd) == -1) {
perror("IOCTL");
exit(1);
}
/* Return the value */
return_val = byte;
} else if (interface == INTERFACE_IO) {
#endif /* HAVE_SMB */
outb(WBIO1, command);
return_val = inb(WBIO2);
#ifdef HAVE_SMB
}
#endif
return return_val;
}
int
main(int argc, char *argv[])
{
double voltage;
int i, iodev, interface, byte;
int ch, delay, cflag, fflag, kflag, nocurses, mflag;
int fandiv[3], fanspeed, temperature[3];
char *device_name;
const char *Vname[] = {
"Vcore1", "Vcore2", "+ 3.3V", "+ 5.0V", "+12.0V", "-12.0V", "- 5.0V"
};
/* Get command-line options */
cflag = 0;
fflag = 0;
kflag = 0;
mflag = 0;
delay = DELAY;
interface = INTERFACE_SMB;
nocurses = 0;
while ((ch = getopt(argc, argv, "hipmr:sv")) != -1)
switch(ch) {
case 'i':
interface = INTERFACE_IO;
break;
case 'p':
nocurses = 1;
break;
case 'r':
delay = atoi(optarg);
break;
case 's':
delay = -1;
break;
case 'm':
mflag = 1;
nocurses = 1;
delay = -1;
break;
default:
usage();
break;
}
argc -= optind;
argv += optind;
if (delay < 1)
delay = -1;
#ifndef HAVE_SMB
interface = INTERFACE_IO;
#endif
/* Open the device */
switch(interface) {
case INTERFACE_SMB:
device_name = SMB_DEV;
break;
default:
device_name = IO_DEV;
break;
}
if ((iodev = open(device_name, O_RDWR)) == -1) {
fprintf(stderr, "Failed to open device %s.\n", device_name);
if (!strncmp(device_name, "/dev/smb", 8)) {
fprintf(stderr, "If your system does not support intpm(4),\n");
fprintf(stderr, "try to use /dev/io (-i flag) or check\n");
} else {
fprintf(stderr, "Check ");
}
fprintf(stderr, "the permissions of %s.\n", device_name);
exit(1);
}
/* Get fan divisors */
byte = get_data(iodev, LM78_FANDIV, interface);
fandiv[0] = LM78_DIV_FROM_DATA((byte >> 4) & 0x03);
fandiv[1] = LM78_DIV_FROM_DATA(byte >> 6);
fandiv[2] = LM78_DIV_FROM_DATA(1);
/* Initialize curses environment */
if (!nocurses) {
initscr();
noecho();
move(1, 1);
printw("%s", "Motherboard Temp");
move(5, 4);
printw("%s", "Fan Speeds");
for (i = 1; i < 4; i++) {
move(i + 6, 4);
printw("%i: rpm", i);
}
move(1, 32);
printw("%s", "Voltages");
for (i = 0; i < 7; i++) {
move(i + 3, 27);
printw("%s: V", Vname[i]);
}
}
/* Start our loop (if applicable) */
do {
/* Get motherboard temp */
if (nocurses && !mflag)
printf("MB temp:\n");
for (i = 0; i < 3; i++)
temperature[i] = LM78_TEMP_FROM_DATA(get_data(iodev, LM78_TEMP, interface), i);
if (mflag)
printf("%i\n", temperature[0]);
else if (nocurses)
printf("%iC / %iF / %iK\n", temperature[0], temperature[1], temperature[2]);
else {
move(3, 1);
printw("%iC / %iF / %iK", temperature[0], temperature[1], temperature[2]);
}
/* Get fan speeds */
if (nocurses && !mflag)
printf("Fans:\n");
for (i = 0; i < 3; i++) {
fanspeed = LM78_FAN_FROM_DATA(get_data(iodev, LM78_FAN(i), interface),
fandiv[i]);
if (mflag)
printf("%i\n", fanspeed);
else if (nocurses)
printf(" %i : %4d rpm\n", i + 1, fanspeed);
else {
move(i + 7, 7);
printw("%4i", fanspeed);
}
}
/* Get voltages */
if (nocurses && !mflag)
printf("Voltages:\n");
for (i = 0; i < 7; i++) {
voltage = LM78_VOLT_FROM_DATA(get_data(iodev, LM78_VOLT(i), interface), i);
if (mflag)
printf("%-8.3f\n", voltage);
else if (nocurses)
printf(" %s :%+8.3fV\n", Vname[i], voltage);
else {
move(i + 3, 35);
printw("%+8.3f", voltage);
}
}
if (!nocurses) {
move(11, 0);
refresh();
} else if (!mflag)
printf("\n");
delay > 0 ? sleep(delay) : 0;
} while (delay != -1);
if (!nocurses) {
echo();
endwin();
}
/* Close the file */
close(iodev);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1