📄 freebsd.c
字号:
#define L_ON_LINE 1#define L_CHARGING 3#define L_UNKNOWN 0xFF/* following two definitions are taken from sys/dev/acpica/acpiio.h */#define ACPI_BATT_STAT_CHARGING 0x0002#define ACPI_BATT_STAT_NOT_PRESENT 0x0007#define ACPI_ACLINE 0#define ACPI_BATT_LIFE 1#define ACPI_BATT_TIME 2#define ACPI_BATT_STATE 3voidgkrellm_sys_battery_read_data(void) { static char *name[] = { "hw.acpi.acline", "hw.acpi.battery.life", "hw.acpi.battery.time", "hw.acpi.battery.state", NULL }; static int oid[CTL_MAXNAME + 2][4]; static size_t oid_len[4] = { sizeof(oid[0]), sizeof(oid[1]), sizeof(oid[2]), sizeof(oid[3]) }; static gboolean first_time_done = FALSE; static gboolean acpi_enabled = FALSE; size_t size; int acpi_info[4]; int i; int f, r; struct apm_info info; gboolean available, on_line, charging; gint percent, time_left; gint batt_num = 0; if (!first_time_done) { first_time_done = TRUE;#ifdef ACPI_SUPPORTS_MULTIPLE_BATTERIES /* * XXX: Disable getting battery information via ACPI * to support multiple batteries via APM sim until * ACPI sysctls support multiple batteries. */ for (i = 0; name[i] != NULL; ++i) { if (gk_sysctlnametomib(name[i], oid[i], &oid_len[i]) < 0) break; } if (name[i] == NULL) acpi_enabled = TRUE;#endif } if (acpi_enabled) { for (i = 0; name[i] != NULL; ++i) { size = sizeof(acpi_info[i]); if (sysctl(oid[i], oid_len[i], &acpi_info[i], &size, NULL, 0) < 0) return; } available = (acpi_info[ACPI_BATT_STATE] != ACPI_BATT_STAT_NOT_PRESENT); on_line = acpi_info[ACPI_ACLINE]; charging = (acpi_info[ACPI_BATT_STATE] == ACPI_BATT_STAT_CHARGING); percent = acpi_info[ACPI_BATT_LIFE]; if (acpi_info[ACPI_BATT_TIME] == 0 && percent > 0) time_left = -1; else time_left = acpi_info[ACPI_BATT_TIME]; gkrellm_battery_assign_data( GKRELLM_BATTERY_COMPOSITE_ID, available, on_line, charging, percent, time_left); return; } if ((f = open(APMDEV, O_RDONLY)) == -1) return; if ((r = ioctl(f, APMIO_GETINFO, &info)) == -1) { close(f); return; } available = (info.ai_batt_stat != L_UNKNOWN || info.ai_acline == L_ON_LINE); on_line = (info.ai_acline == L_ON_LINE) ? TRUE : FALSE; charging = (info.ai_batt_stat == L_CHARGING) ? TRUE : FALSE; percent = info.ai_batt_life;#if defined(APM_GETCAPABILITIES) if (info.ai_batt_time == -1 || (info.ai_batt_time == 0 && percent > 0)) time_left = -1; else time_left = info.ai_batt_time / 60;#else time_left = -1;#endif gkrellm_battery_assign_data(GKRELLM_BATTERY_COMPOSITE_ID, available, on_line, charging, percent, time_left);#if defined(APMIO_GETPWSTATUS) if (info.ai_infoversion >= 1 && info.ai_batteries != (u_int) -1 && info.ai_batteries > 1) { gint i; struct apm_pwstatus aps; for (i = 0; i < info.ai_batteries; ++i) { bzero(&aps, sizeof(aps)); aps.ap_device = PMDV_BATT0 + i; if (ioctl(f, APMIO_GETPWSTATUS, &aps) == -1 || (aps.ap_batt_flag != 255 && (aps.ap_batt_flag & APM_BATT_NOT_PRESENT))) continue; available = (aps.ap_batt_stat != L_UNKNOWN || aps.ap_acline == L_ON_LINE); on_line = (aps.ap_acline == L_ON_LINE) ? TRUE : FALSE; charging = (aps.ap_batt_stat == L_CHARGING) ? TRUE : FALSE; percent = aps.ap_batt_life; if (aps.ap_batt_time == -1 || (aps.ap_batt_time == 0 && percent > 0)) time_left = -1; else time_left = aps.ap_batt_time / 60; gkrellm_battery_assign_data(batt_num++, available, on_line, charging, percent, time_left); } }#endif close(f); }gbooleangkrellm_sys_battery_init(void) { return TRUE; }#elsevoidgkrellm_sys_battery_read_data(void) { }gbooleangkrellm_sys_battery_init(void) { return FALSE; }#endif/* ===================================================================== *//* Sensor monitor interface */#if defined(__i386__)typedef struct { gchar *name; gfloat factor; gfloat offset; gchar *vref; } VoltDefault; /* Tables of voltage correction factors and offsets derived from the | compute lines in sensors.conf. See the README file. */ /* "lm78-*" "lm78-j-*" "lm79-*" "w83781d-*" "sis5595-*" "as99127f-*" */ /* Values from LM78/LM79 data sheets */static VoltDefault voltdefault0[] = { { "Vcor1", 1.0, 0, NULL }, { "Vcor2", 1.0, 0, NULL }, { "+3.3V", 1.0, 0, NULL }, { "+5V", 1.68, 0, NULL }, /* in3 ((6.8/10)+1)*@ */ { "+12V", 4.0, 0, NULL }, /* in4 ((30/10)+1)*@ */ { "-12V", -4.0, 0, NULL }, /* in5 -(240/60)*@ */ { "-5V", -1.667, 0, NULL } /* in6 -(100/60)*@ */ };#include <dirent.h>#include <osreldate.h>#include <machine/cpufunc.h>#if __FreeBSD_version >= 500042#include <dev/smbus/smb.h>#elif __FreeBSD_version >= 300000#include <machine/smb.h>#endif/* Interface types */#define INTERFACE_IO 0#define INTERFACE_SMB 1#define INTERFACE_ACPI 2/* Addresses to use for /dev/io */#define WBIO1 0x295#define WBIO2 0x296/* LM78/79 addresses */#define LM78_VOLT(val) (0x20 + (val))#define LM78_TEMP 0x27#define LM78_FAN(val) (0x28 + (val))#define LM78_FANDIV 0x47#define SENSORS_DIR "/dev"#define TZ_ZEROC 2732#define TZ_KELVTOC(x) ((gfloat)((x) - TZ_ZEROC) / 10.0)static gintget_data(int iodev, u_char command, int interface, u_char *ret) { u_char byte = 0; if (interface == INTERFACE_IO) { outb(WBIO1, command); byte = inb(WBIO2); }#if __FreeBSD_version >= 300000 else if (interface == INTERFACE_SMB) { struct smbcmd cmd; bzero(&cmd, sizeof(cmd)); cmd.data.byte_ptr = &byte; cmd.slave = 0x5a; cmd.cmd = command; if (ioctl(iodev, SMB_READB, (caddr_t)&cmd) == -1) { close(iodev); return FALSE; } }#endif else { return FALSE; } if (byte == 0xff) return FALSE; *ret = byte; return TRUE; }gbooleangkrellm_sys_sensors_get_temperature(gchar *path, gint id, gint iodev, gint interface, gfloat *temp) { u_char byte; if (interface == MBMON_INTERFACE) { gkrellm_sys_sensors_mbmon_check(FALSE); return gkrellm_sys_sensors_mbmon_get_value(path, temp); } if (interface == INTERFACE_ACPI) { int value; size_t size = sizeof(value); if (sysctlbyname(path, &value, &size, NULL, 0) < 0) return FALSE; if (temp) *temp = (gfloat) TZ_KELVTOC(value); return TRUE; } if (get_data(iodev, LM78_TEMP, interface, &byte)) { if (temp) *temp = (gfloat) byte; return TRUE; } return FALSE; }gbooleangkrellm_sys_sensors_get_fan(gchar *path, gint id, gint iodev, gint interface, gfloat *fan) { u_char byte; if (interface == MBMON_INTERFACE) { gkrellm_sys_sensors_mbmon_check(FALSE); return gkrellm_sys_sensors_mbmon_get_value(path, fan); } if (get_data(iodev, LM78_FAN(id), interface, &byte)) { if (byte == 0) return FALSE; if (fan) *fan = 1.35E6 / (gfloat) byte; return TRUE; } return FALSE; }gbooleangkrellm_sys_sensors_get_voltage(gchar *path, gint id, gint iodev, gint interface, gfloat *volt) { u_char byte; if (interface == MBMON_INTERFACE) { gkrellm_sys_sensors_mbmon_check(FALSE); return gkrellm_sys_sensors_mbmon_get_value(path, volt); } if (get_data(iodev, LM78_VOLT(id), interface, &byte)) { if (volt) *volt = (gfloat) byte / 64.0; return TRUE; } return FALSE; }struct freebsd_sensor { gint type; gchar *id_name; gint id; gint iodev; gint inter; gfloat factor; gfloat offset; gchar *default_label;};static GList *freebsd_sensor_list;gbooleangkrellm_sys_sensors_init(void) { gchar mib_name[256], label[8]; gint interface, id; int oid_acpi_temp[CTL_MAXNAME + 2]; size_t oid_acpi_temp_len = sizeof(oid_acpi_temp); GList *list; struct freebsd_sensor *sensor; /* Do intial daemon reads to get sensors loaded into sensors.c */ gkrellm_sys_sensors_mbmon_check(TRUE); for (id = 0;;) { snprintf(mib_name, sizeof(mib_name), "hw.acpi.thermal.tz%d.temperature", id); if (gk_sysctlnametomib(mib_name, oid_acpi_temp, &oid_acpi_temp_len) < 0) break; interface = INTERFACE_ACPI; if (!gkrellm_sys_sensors_get_temperature(mib_name, 0, 0, interface, NULL)) continue; snprintf(label, sizeof(label), "tz%d", id); gkrellm_sensors_add_sensor(SENSOR_TEMPERATURE, NULL, mib_name, 0, 0, interface, 1.0, 0.0, NULL, label); } if (freebsd_sensor_list) { for (list = freebsd_sensor_list; list; list = list->next) { sensor = (struct freebsd_sensor *)list->data; gkrellm_sensors_add_sensor(sensor->type, NULL, sensor->id_name, sensor->id, sensor->iodev, sensor->inter, sensor->factor, sensor->offset, NULL, sensor->default_label); } } return (TRUE); }static gbooleansensors_add_sensor(gint type, gchar *id_name, gint id, gint iodev, gint inter, gfloat factor, gfloat offset, gchar *default_label){ struct freebsd_sensor *sensor; if ((sensor = g_new0(struct freebsd_sensor, 1)) == NULL) return FALSE; sensor->type = type; sensor->id_name = g_strdup(id_name); sensor->id = id; sensor->iodev = iodev; sensor->inter = inter; sensor->factor = factor; sensor->offset = offset; sensor->default_label = default_label ? g_strdup(default_label) : NULL; if (g_list_append(freebsd_sensor_list, sensor) == NULL) { g_free(sensor->id_name); if (sensor->default_label) g_free(sensor->default_label); g_free(sensor); return FALSE; } return TRUE;}static voidscan_for_sensors(void) { gchar *chip_dir = SENSORS_DIR;#if __FreeBSD_version >= 300000 DIR *dir; struct dirent *dentry;#endif gchar temp_file[256], id_name[8]; gint iodev = -1, interface = -1, id; gint fandiv[3]; u_char byte; gboolean found_sensors = FALSE;#if __FreeBSD_version >= 300000 if ((dir = opendir(chip_dir)) != NULL) { while ((dentry = readdir(dir)) != NULL) { if (dentry->d_name[0] == '.' || dentry->d_ino <= 0) continue; if (strncmp(dentry->d_name, "smb", 3) != 0) continue; snprintf(temp_file, sizeof(temp_file), "%s/%s", chip_dir, dentry->d_name); if ((iodev = open(temp_file, O_RDWR)) == -1) continue; sprintf(id_name, "%s%3s", "temp", dentry->d_name + 3); interface = INTERFACE_SMB; if (!gkrellm_sys_sensors_get_temperature(NULL, 0, iodev, interface, NULL)) { close(iodev); continue; } sensors_add_sensor(SENSOR_TEMPERATURE, id_name, 0, iodev, interface, 1.0, 0.0, NULL); found_sensors = TRUE; break; } closedir(dir); }#endif if (!found_sensors) { snprintf(temp_file, sizeof(temp_file), "%s/%s", chip_dir, "io"); if ((iodev = open(temp_file, O_RDWR)) == -1) return; interface = INTERFACE_IO; if (!gkrellm_sys_sensors_get_temperature(NULL, 0, iodev, interface, NULL)) { close(iodev); return; } sensors_add_sensor(SENSOR_TEMPERATURE, "temp0", 0, iodev, interface, 1.0, 0.0, NULL); found_sensors = TRUE; } if (found_sensors) { if (get_data(iodev, LM78_FANDIV, interface, &byte)) { fandiv[0] = 1 << ((byte & 0x30) >> 4); fandiv[1] = 1 << ((byte & 0xc0) >> 6); fandiv[2] = 2; for (id = 0; id < 3; ++id) { if (!gkrellm_sys_sensors_get_fan(NULL, id, iodev, interface, NULL)) continue; sprintf(id_name, "%s%d", "fan", id); sensors_add_sensor(SENSOR_FAN, id_name, id, iodev, interface, 1.0 / (gfloat) fandiv[id], 0.0, NULL); } } for (id = 0; id < 7; ++id) { if (!gkrellm_sys_sensors_get_voltage(NULL, id, iodev, interface, NULL)) continue; sprintf(id_name, "%s%d", "in", id); sensors_add_sensor(SENSOR_VOLTAGE, id_name, id, iodev, interface, voltdefault0[id].factor, 0.0, voltdefault0[id].name); } } }#elsegbooleangkrellm_sys_sensors_get_temperature(gchar *path, gint id, gint iodev, gint interface, gfloat *temp) { return FALSE; }gbooleangkrellm_sys_sensors_get_fan(gchar *path, gint id, gint iodev, gint interface, gfloat *fan) { return FALSE; }gbooleangkrellm_sys_sensors_get_voltage(gchar *path, gint id, gint iodev, gint interface, gfloat *volt) { return FALSE; }gbooleangkrellm_sys_sensors_init(void) { return FALSE; }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -