common/recipes-lib/obmc-pal/files/obmc_pal_sensors.c (888 lines of code) (raw):
/*
*
* Copyright 2017-present Facebook. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <float.h>
#include <time.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <openbmc/kv.h>
#include "obmc-pal.h"
#include "obmc_pal_sensors.h"
#ifdef DBUS_SENSOR_SVC
#include <openbmc/sensor-svc-client.h>
#endif
#ifdef DEBUG
#define DEBUG_STR(...) syslog(LOG_WARNING, __VA_ARGS__)
#else
#define DEBUG_STR(...)
#endif
#define MAX_DATA_NUM 2000
#define CACHE_READ_RETRY 5
typedef struct {
long log_time;
float value;
} sensor_data_t;
typedef struct {
int index;
sensor_data_t data[MAX_DATA_NUM];
} sensor_shm_t;
typedef struct {
long log_time;
float sum;
float count;
float avg;
float max;
float min;
} sensor_coarse_data_t;
typedef struct {
int index;
sensor_coarse_data_t data[MAX_COARSE_DATA_NUM];
} sensor_coarse_shm_t;
static int
sensor_key_get(uint8_t fru, uint8_t sensor_num, char *key)
{
char fruname[32];
if (fru == AGGREGATE_SENSOR_FRU_ID) {
strcpy(fruname, AGGREGATE_SENSOR_FRU_NAME);
} else {
if (pal_get_fru_name(fru, fruname))
return -1;
}
sprintf(key, "%s_sensor%d", fruname, sensor_num);
return 0;
}
static int
sensor_coarse_key_get(uint8_t fru, uint8_t sensor_num, char *key)
{
int ret = sensor_key_get(fru, sensor_num, key);
if (ret) {
return ret;
}
strcat(key, "_coarse");
return 0;
}
static int
cache_set_coarse_history(char *key, float value) {
int fd;
int share_size = sizeof(sensor_coarse_shm_t);
void *ptr;
sensor_coarse_shm_t *snr_shm;
long current_time;
int ret = ERR_FAILURE;
fd = shm_open(key, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
DEBUG_STR("%s: shm_open %s failed, errno = %d", __FUNCTION__, key, errno);
return -1;
}
if (flock(fd, LOCK_EX) < 0) {
syslog(LOG_INFO, "%s: file-lock %s failed errno = %d\n", __FUNCTION__, key, errno);
goto close_bail;
}
if (ftruncate(fd, share_size) != 0) {
syslog(LOG_INFO, "%s: truncate %s failed errno = %d\n", __FUNCTION__, key, errno);
goto close_bail;
}
ptr = mmap(NULL, share_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
syslog(LOG_INFO, "%s: mmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
snr_shm = (sensor_coarse_shm_t *)ptr;
current_time = time(NULL);
if (snr_shm->data[snr_shm->index].log_time == 0) {
sensor_coarse_data_t *s = &snr_shm->data[snr_shm->index];
s->log_time = current_time;
s->avg = s->sum = s->max = s->min = value;
s->count = 1;
} else {
sensor_coarse_data_t *s = &snr_shm->data[snr_shm->index];
/* If the log was started less than an hour ago, then
* continue to log to this entry */
if (difftime(current_time, s->log_time) < COARSE_THRESHOLD) {
s->sum += value;
s->count += 1;
if (value > s->max)
s->max = value;
if (value < s->min)
s->min = value;
s->avg = s->sum / s->count;
} else {
/* Start logging to the next entry */
snr_shm->index = (snr_shm->index + 1) % MAX_COARSE_DATA_NUM;
s = &snr_shm->data[snr_shm->index];
memset(s, 0, sizeof(*s));
s->log_time = current_time;
s->avg = s->sum = s->max = s->min = value;
s->count = 1;
}
}
if (munmap(ptr, share_size) != 0) {
syslog(LOG_INFO, "%s: munmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
ret = 0;
unlock_bail:
if (flock(fd, LOCK_UN) < 0) {
syslog(LOG_INFO, "%s: file-unlock %s failed errno = %d\n", __FUNCTION__, key, errno);
ret = -1;
}
close_bail:
close(fd);
return ret;
}
static int
cache_set_history(char *key, float value) {
int fd;
int share_size = sizeof(sensor_shm_t);
void *ptr;
sensor_shm_t *snr_shm;
int ret = ERR_FAILURE;
fd = shm_open(key, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
DEBUG_STR("%s: shm_open %s failed, errno = %d", __FUNCTION__, key, errno);
return -1;
}
if (flock(fd, LOCK_EX) < 0) {
syslog(LOG_INFO, "%s: file-lock %s failed errno = %d\n", __FUNCTION__, key, errno);
goto close_bail;
}
if (ftruncate(fd, share_size) != 0) {
syslog(LOG_INFO, "%s: truncate %s failed errno = %d\n", __FUNCTION__, key, errno);
goto close_bail;
}
ptr = mmap(NULL, share_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
syslog(LOG_INFO, "%s: mmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
snr_shm = (sensor_shm_t *)ptr;
snr_shm->data[snr_shm->index].log_time = time(NULL);
snr_shm->data[snr_shm->index].value = value;
snr_shm->index = (snr_shm->index + 1) % MAX_DATA_NUM;
if (munmap(ptr, share_size) != 0) {
syslog(LOG_INFO, "%s: munmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
ret = 0;
unlock_bail:
if (flock(fd, LOCK_UN) < 0) {
syslog(LOG_INFO, "%s: file-unlock %s failed errno = %d\n", __FUNCTION__, key, errno);
ret = -1;
}
close_bail:
close(fd);
return ret;
}
int __attribute__((weak))
sensor_cache_read(uint8_t fru, uint8_t sensor_num, float *value)
{
#ifndef DBUS_SENSOR_SVC
int ret;
char key[MAX_KEY_LEN];
char str[MAX_VALUE_LEN];
int retry = 0;
if (sensor_key_get(fru, sensor_num, key))
return ERR_UNKNOWN_FRU;
for (retry = 0; retry < CACHE_READ_RETRY; retry++) {
memset(str, 0, MAX_VALUE_LEN);
if (!(ret = kv_get(key, str, NULL, 0))) {
break;
}
}
if (ret < 0) {
DEBUG_STR("sensor_cache_read: cache_get %s failed.\n", key);
return ERR_SENSOR_NA;
}
if (0 == strcmp(str, "NA")) {
return ERR_SENSOR_NA;
}
*((float*)value) = atof(str);
return 0;
#else
return sensor_svc_read(fru, sensor_num, value);
#endif
}
int
sensor_cache_write(uint8_t fru, uint8_t sensor_num, bool available, float value)
{
char key[MAX_KEY_LEN];
char str[MAX_VALUE_LEN];
int ret;
if (sensor_key_get(fru, sensor_num, key))
return ERR_UNKNOWN_FRU;
if (available)
sprintf(str, "%.2f", value);
else
strcpy(str, "NA");
ret = kv_set(key, str, 0, 0);
if (ret) {
DEBUG_STR("sensor_cache_write: cache_set %s failed.\n", key);
return ERR_FAILURE;
}
if (available) {
cache_set_history(key, value);
if (sensor_coarse_key_get(fru, sensor_num, key) == 0) {
cache_set_coarse_history(key, value);
}
}
return 0;
}
int sensor_raw_read(uint8_t fru, uint8_t sensor_num, float *value)
{
#ifdef DBUS_SENSOR_SVC
int ret = sensor_svc_raw_read(fru, sensor_num, value);
#else
int ret = pal_sensor_read_raw(fru, sensor_num, value);
#endif
if (!ret)
sensor_cache_write(fru, sensor_num, true, *value);
else if (ret == ERR_SENSOR_NA)
sensor_cache_write(fru, sensor_num, false, 0.0);
return ret;
}
static int
sensor_read_short_history(uint8_t fru, uint8_t sensor_num, float *min,
float *average, float *max, int start_time)
{
char key[MAX_KEY_LEN] = {0};
int fd;
int share_size = sizeof(sensor_shm_t);
void *ptr;
sensor_shm_t *snr_shm;
int16_t read_index;
uint16_t count = 0;
float read_val;
double total = 0;
int ret = ERR_FAILURE;
if (sensor_key_get(fru, sensor_num, key))
return ERR_UNKNOWN_FRU;
fd = shm_open(key, O_RDONLY, S_IRUSR | S_IWUSR);
if (fd < 0) {
DEBUG_STR("%s: shm_open %s failed, errno = %d", __FUNCTION__, key, errno);
return ERR_FAILURE;
}
if (flock(fd, LOCK_EX) < 0) {
syslog(LOG_INFO, "%s: file-lock %s failed errno = %d\n", __FUNCTION__, key, errno);
goto close_bail;
}
ptr = mmap(NULL, share_size, PROT_READ, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
syslog(LOG_INFO, "%s: mmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
snr_shm = (sensor_shm_t *)ptr;
read_index = snr_shm->index - 1;
if (read_index < 0) {
read_index += MAX_DATA_NUM;
}
read_val = snr_shm->data[read_index].value;
*min = read_val;
*max = read_val;
while ((snr_shm->data[read_index].log_time >= start_time) && (count < MAX_DATA_NUM)) {
read_val = snr_shm->data[read_index].value;
if (read_val > *max)
*max = read_val;
if (read_val < *min)
*min = read_val;
total += read_val;
count++;
if ((--read_index) < 0) {
read_index += MAX_DATA_NUM;
}
}
if (munmap(ptr, share_size) != 0) {
syslog(LOG_INFO, "%s: munmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
/* If none found in history, just return the cached value */
if (!count) {
float read_value;
ret = sensor_cache_read(fru, sensor_num, &read_value);
if (ret)
return ret;
total = *min = *max = read_value;
count = 1;
}
*average = total / count;
ret = 0;
unlock_bail:
if (flock(fd, LOCK_UN) < 0) {
syslog(LOG_INFO, "%s: file-unlock %s failed errno = %d\n", __FUNCTION__, key, errno);
ret = -1;
}
close_bail:
close(fd);
return ret;
}
static int
sensor_read_long_history(uint8_t fru, uint8_t sensor_num, float *min,
float *average, float *max, int start_time)
{
char key[MAX_KEY_LEN] = {0};
int fd;
int share_size = sizeof(sensor_coarse_shm_t);
void *ptr;
sensor_coarse_shm_t *snr_shm;
sensor_coarse_data_t *s;
int16_t read_index;
uint16_t count = 0;
double total = 0;
int ret = ERR_FAILURE;
if (sensor_coarse_key_get(fru, sensor_num, key))
return ERR_UNKNOWN_FRU;
fd = shm_open(key, O_RDONLY, S_IRUSR | S_IWUSR);
if (fd < 0) {
DEBUG_STR("%s: shm_open %s failed, errno = %d", __FUNCTION__, key, errno);
return ERR_FAILURE;
}
if (flock(fd, LOCK_EX) < 0) {
syslog(LOG_INFO, "%s: file-lock %s failed errno = %d\n", __FUNCTION__, key, errno);
goto close_bail;
}
ptr = mmap(NULL, share_size, PROT_READ, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
syslog(LOG_INFO, "%s: mmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
snr_shm = (sensor_coarse_shm_t *)ptr;
read_index = snr_shm->index;
total = 0;
*max = -FLT_MAX;
*min = FLT_MAX;
while (count < MAX_COARSE_DATA_NUM) {
s = &snr_shm->data[read_index];
if (s->log_time < start_time) {
break;
}
if (s->max > *max)
*max = s->max;
if (s->min < *min)
*min = s->min;
total += s->avg;
count++;
if ((--read_index) < 0) {
read_index += MAX_COARSE_DATA_NUM;
}
}
if (munmap(ptr, share_size) != 0) {
syslog(LOG_INFO, "%s: munmap %s failed, errno = %d", __FUNCTION__, key, errno);
goto unlock_bail;
}
/* If none found in history, just return the cached value */
if (!count) {
float read_value;
ret = sensor_cache_read(fru, sensor_num, &read_value);
if (ret)
return ret;
total = *min = *max = read_value;
count = 1;
}
*average = total / count;
ret = 0;
unlock_bail:
if (flock(fd, LOCK_UN) < 0) {
syslog(LOG_INFO, "%s: file-unlock %s failed errno = %d\n", __FUNCTION__, key, errno);
ret = -1;
}
close_bail:
close(fd);
return ret;
}
int
sensor_read_history(uint8_t fru, uint8_t sensor_num, float *min, float *average, float *max, int start_time)
{
long current_time = time(NULL);
/* If requested start is greater than the coarse threshold (mostly an hour),
* then go through the coarse stats to compute the max,min avg. else use the
* fine grained data to get the values */
if (difftime(current_time, start_time) > COARSE_THRESHOLD) {
return sensor_read_long_history(fru, sensor_num, min, average, max, start_time);
}
return sensor_read_short_history(fru, sensor_num, min, average, max, start_time);
}
static int sensor_clear_history_helper(char *shm_name, int share_size)
{
int fd;
long *shm;
int ret = ERR_FAILURE;
fd = shm_open(shm_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
return ERR_FAILURE;
}
if (flock(fd, LOCK_EX) < 0) {
syslog(LOG_INFO, "%s: file-lock %s failed errno = %d\n", __FUNCTION__, shm_name, errno);
goto close_bail;
}
if (ftruncate(fd, share_size) != 0) {
syslog(LOG_INFO, "%s: truncate %s failed errno = %d\n", __FUNCTION__, shm_name, errno);
goto close_bail;
}
shm = (long *)mmap(NULL, share_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shm == MAP_FAILED) {
syslog(LOG_INFO, "%s: mmap %s failed, errno = %d", __FUNCTION__, shm_name, errno);
goto unlock_bail;
}
memset(shm, 0, share_size);
if (munmap(shm, share_size) != 0) {
syslog(LOG_INFO, "%s: munmap %s failed, errno = %d", __FUNCTION__, shm_name, errno);
goto unlock_bail;
}
ret = 0;
unlock_bail:
if (flock(fd, LOCK_UN) < 0) {
syslog(LOG_INFO, "%s: file-unlock %s failed errno = %d\n", __FUNCTION__, shm_name, errno);
ret = -1;
}
close_bail:
close(fd);
return ret;
}
int sensor_clear_history(uint8_t fru, uint8_t sensor_num)
{
char key[MAX_KEY_LEN] = {0};
int ret1, ret2;
if (sensor_key_get(fru, sensor_num, key))
return ERR_UNKNOWN_FRU;
ret1 = sensor_clear_history_helper(key, sizeof(sensor_shm_t));
if (ret1) {
syslog(LOG_INFO, "Clearing history failed: %d\n", ret1);
}
if (sensor_coarse_key_get(fru, sensor_num, key))
return ERR_UNKNOWN_FRU;
ret2 = sensor_clear_history_helper(key, sizeof(sensor_coarse_shm_t));
if (ret2) {
syslog(LOG_INFO, "Clearing coarse history failed: %d\n", ret2);
}
return ret1 || ret2 ? ERR_FAILURE : 0;
}
int __attribute__((weak))
pal_get_fru_sensor_list(uint8_t fru, uint8_t **sensor_list, int *cnt)
{
return PAL_EOK;
}
bool __attribute__((weak))
pal_sensor_is_source_host(uint8_t fru, uint8_t sensor_id)
{
return false;
}
bool __attribute__((weak))
pal_is_host_snr_available(uint8_t fru, uint8_t sensor_id)
{
return false;
}
int __attribute__((weak))
pal_correct_sensor_reading_from_cache(uint8_t fru, uint8_t sensor_id, float *value)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_get_sensor_poll_interval(uint8_t fru, uint8_t sensor_num, uint32_t *value)
{
*value = 2;
return PAL_EOK;
}
int __attribute__((weak))
pal_alter_sensor_poll_interval(uint8_t fru, uint8_t sensor_num, uint32_t *value)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_get_fru_discrete_list(uint8_t fru, uint8_t **sensor_list, int *cnt)
{
*cnt = 0;
return PAL_EOK;
}
int __attribute__((weak))
pal_init_sensor_check(uint8_t fru, uint8_t snr_num, void *snr)
{
return PAL_EOK;
}
bool __attribute__((weak))
pal_sensor_is_cached(uint8_t fru, uint8_t sensor_num)
{
return true;
}
int __attribute__((weak))
pal_sensor_discrete_check(uint8_t fru, uint8_t snr_num, char *snr_name,
uint8_t o_val, uint8_t n_val)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_sensor_read_raw(uint8_t fru, uint8_t sensor_num, void *value)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_sensor_threshold_flag(uint8_t fru, uint8_t snr_num, uint16_t *flag)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_alter_sensor_thresh_flag(uint8_t fru, uint8_t snr_num, uint16_t *flag) {
return PAL_EOK;
}
int __attribute__((weak))
pal_get_sensor_name(uint8_t fru, uint8_t sensor_num, char *name)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_get_sensor_units(uint8_t fru, uint8_t sensor_num, char *units)
{
return PAL_EOK;
}
int __attribute__((weak))
pal_get_sensor_threshold(uint8_t fru, uint8_t sensor_num, uint8_t thresh, void *value)
{
return PAL_EOK;
}
bool __attribute__((weak))
pal_is_sensor_existing(uint8_t fru, uint8_t snr_num) {
int i;
int ret;
int sensor_cnt;
uint8_t *sensor_list;
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
printf("%s: Fail to get fru%d sensor list\n",__func__, fru);
return false;
}
for (i = 0; i < sensor_cnt; i++) {
if (snr_num == sensor_list[i])
return true;
}
return false;
}
int __attribute__((weak))
pal_copy_all_thresh_to_file(uint8_t fru, thresh_sensor_t *sinfo) {
int fd;
uint8_t bytes_wd = 0;
uint8_t snr_num = 0;
int ret;
char fru_name[32];
int sensor_cnt;
uint8_t *sensor_list;
char fpath[128] = {0};
int i;
ret = pal_get_fru_name(fru, fru_name);
if (ret < 0) {
printf("%s: Fail to get fru%d name\n",__func__,fru);
return ret;
}
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
return ret;
}
sprintf(fpath, INIT_THRESHOLD_BIN, fru_name);
fd = open(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
syslog(LOG_ERR, "%s: open failed for %s, errno : %d %s\n", __func__, fpath, errno, strerror(errno));
return -1;
}
for (i = 0; i < sensor_cnt; i++) {
snr_num = sensor_list[i];
bytes_wd = write(fd, &sinfo[snr_num], sizeof(thresh_sensor_t));
if (bytes_wd != sizeof(thresh_sensor_t)) {
syslog(LOG_ERR, "%s: write returns %d bytes\n", __func__, bytes_wd);
close(fd);
return -1;
}
}
close(fd);
return 0;
}
int __attribute__((weak))
pal_sensor_sdr_init(uint8_t fru, void *sinfo)
{
return -1;
}
int __attribute__((weak))
pal_get_all_thresh_from_file(uint8_t fru, thresh_sensor_t *sinfo, int mode) {
int fd;
int cnt = 0;
uint8_t buf[MAX_THERSH_LEN] = {0};
uint8_t bytes_rd = 0;
int ret;
uint8_t snr_num = 0;
char fru_name[16];
int sensor_cnt;
uint8_t *sensor_list;
char fpath[128] = {0};
char cmd[256] = {0};
int curr_state = 0;
ret = pal_get_fru_name(fru, fru_name);
if (ret)
printf("%s: Fail to get fru%d name\n",__func__,fru);
switch (mode) {
case SENSORD_MODE_TESTING:
sprintf(fpath, THRESHOLD_BIN, fru_name);
break;
case SENSORD_MODE_NORMAL:
sprintf(fpath, INIT_THRESHOLD_BIN, fru_name);
break;
default:
sprintf(fpath, INIT_THRESHOLD_BIN, fru_name);
break;
}
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
return ret;
}
if (!sensor_list) {
syslog(LOG_ERR, "%s: pal_get_fru_sensor_list returns null list", __func__);
return -1;
}
fd = open(fpath, O_RDONLY);
if (fd < 0) {
syslog(LOG_ERR, "%s: open failed for %s, errno : %d %s\n", __func__, fpath, errno, strerror(errno));
return -1;
}
while ((bytes_rd = read(fd, buf, sizeof(thresh_sensor_t))) > 0) {
if (bytes_rd != sizeof(thresh_sensor_t)) {
syslog(LOG_ERR, "%s: read returns %d bytes\n", __func__, bytes_rd);
close(fd);
return -1;
}
snr_num = sensor_list[cnt];
curr_state = sinfo[snr_num].curr_state;
memcpy(&sinfo[snr_num], &buf, sizeof(thresh_sensor_t));
sinfo[snr_num].curr_state = curr_state;
memset(buf, 0, sizeof(buf));
cnt++;
pal_init_sensor_check(fru, snr_num, (void *)&sinfo[snr_num]);
if (cnt == sensor_cnt) {
syslog(LOG_ERR, "%s: cnt = %d", __func__, cnt);
break;
}
}
close(fd);
// Remove reinit file
memset(fpath, 0, sizeof(fpath));
sprintf(fpath, THRESHOLD_RE_FLAG, fru_name);
if (0 == access(fpath, F_OK)) {
sprintf(cmd,"rm -rf %s",fpath);
if (system(cmd) != 0) {
syslog(LOG_ERR, "%s failed", cmd);
}
}
return 0;
}
int __attribute__((weak))
pal_get_thresh_from_file(uint8_t fru, uint8_t snr_num, thresh_sensor_t *sinfo) {
int fd;
int cnt = 0;
uint8_t buf[MAX_THERSH_LEN] = {0};
uint8_t bytes_rd = 0;
int ret;
char fru_name[16];
int sensor_cnt;
uint8_t *sensor_list;
char fpath[64] = {0};
int curr_state;
ret = pal_get_fru_name(fru, fru_name);
if (ret < 0)
printf("%s: Fail to get fru%d name\n",__func__,fru);
sprintf(fpath, THRESHOLD_BIN, fru_name);
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
return ret;
}
fd = open(fpath, O_RDONLY);
if (fd < 0) {
syslog(LOG_ERR, "%s: open failed for %s, errno : %d %s\n", __func__, fpath, errno, strerror(errno));
return -1;
}
while (cnt != sensor_cnt) {
lseek(fd, cnt*sizeof(thresh_sensor_t), SEEK_SET);
if (snr_num == sensor_list[cnt]) {
bytes_rd = read(fd, buf, sizeof(thresh_sensor_t));
if (bytes_rd != sizeof(thresh_sensor_t)) {
syslog(LOG_ERR, "%s: read returns %d bytes\n", __func__, bytes_rd);
close(fd);
return -1;
}
curr_state = sinfo->curr_state;
memcpy(sinfo, buf, sizeof(thresh_sensor_t));
sinfo->curr_state = curr_state;
break;
}
cnt++;
}
close(fd);
return 0;
}
int __attribute__((weak))
pal_copy_thresh_to_file(uint8_t fru, uint8_t snr_num, thresh_sensor_t *sinfo) {
int fd;
int cnt = 0;
uint8_t bytes_wd = 0;
int ret;
char fru_name[16];
int sensor_cnt;
uint8_t *sensor_list;
char fpath[64] = {0};
ret = pal_get_fru_name(fru, fru_name);
if (ret < 0) {
printf("%s: Fail to get fru%d name\n",__func__,fru);
return ret;
}
sprintf(fpath, THRESHOLD_BIN, fru_name);
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
return ret;
}
fd = open(fpath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
syslog(LOG_ERR, "%s: open failed for %s, errno : %d %s\n", __func__, fpath, errno, strerror(errno));
return -1;
}
while (cnt != sensor_cnt) {
lseek(fd, cnt*sizeof(thresh_sensor_t), SEEK_SET);
if (snr_num == sensor_list[cnt]) {
bytes_wd = write(fd, sinfo, sizeof(thresh_sensor_t));
if (bytes_wd != sizeof(thresh_sensor_t)) {
syslog(LOG_ERR, "%s: read returns %d bytes\n", __func__, bytes_wd);
close(fd);
return -1;
}
break;
}
cnt++;
}
close(fd);
return 0;
}
int __attribute__((weak))
pal_sensor_thresh_modify(uint8_t fru, uint8_t sensor_num, uint8_t thresh_type, float value) {
int ret = -1;
thresh_sensor_t snr;
char fru_name[16];
char fpath[128] = {0};
char initpath[128] = {0};
char cmd[512] = {0};
ret = pal_get_fru_name(fru, fru_name);
if (ret < 0) {
printf("%s: Fail to get fru%d name\n",__func__,fru);
return ret;
}
memset(fpath, 0, sizeof(fpath));
sprintf(fpath, THRESHOLD_BIN, fru_name);
memset(initpath, 0, sizeof(initpath));
sprintf(initpath, INIT_THRESHOLD_BIN, fru_name);
if (0 != access(fpath, F_OK)) {
sprintf(cmd,"cp -rf %s %s", initpath, fpath);
if (system(cmd) != 0) {
syslog(LOG_ERR, "%s failed", cmd);
}
}
ret = pal_get_thresh_from_file(fru, sensor_num, &snr);
if (ret < 0) {
syslog(LOG_ERR, "%s: Fail to get %s sensor threshold file\n",__func__,fru_name);
return ret;
}
switch (thresh_type) {
case UCR_THRESH:
if (((snr.flag & GETMASK(UNR_THRESH)) && (value > snr.unr_thresh)) ||
((snr.flag & GETMASK(UNC_THRESH)) && (value < snr.unc_thresh)) ||
((snr.flag & GETMASK(LNC_THRESH)) && (value < snr.lnc_thresh)) ||
((snr.flag & GETMASK(LCR_THRESH)) && (value < snr.lcr_thresh)) ||
((snr.flag & GETMASK(LNR_THRESH)) && (value < snr.lnr_thresh))) {
return -1;
}
snr.ucr_thresh = value;
snr.flag |= SETMASK(UCR_THRESH);
break;
case UNC_THRESH:
if (((snr.flag & GETMASK(UNR_THRESH)) && (value > snr.unr_thresh)) ||
((snr.flag & GETMASK(UCR_THRESH)) && (value > snr.ucr_thresh)) ||
((snr.flag & GETMASK(LNC_THRESH)) && (value < snr.lnc_thresh)) ||
((snr.flag & GETMASK(LCR_THRESH)) && (value < snr.lcr_thresh)) ||
((snr.flag & GETMASK(LNR_THRESH)) && (value < snr.lnr_thresh))) {
return -1;
}
snr.unc_thresh = value;
snr.flag |= SETMASK(UNC_THRESH);
break;
case UNR_THRESH:
if (((snr.flag & GETMASK(UCR_THRESH)) && (value < snr.ucr_thresh)) ||
((snr.flag & GETMASK(UNC_THRESH)) && (value < snr.unc_thresh)) ||
((snr.flag & GETMASK(LNC_THRESH)) && (value < snr.lnc_thresh)) ||
((snr.flag & GETMASK(LCR_THRESH)) && (value < snr.lcr_thresh)) ||
((snr.flag & GETMASK(LNR_THRESH)) && (value < snr.lnr_thresh))) {
return -1;
}
snr.unr_thresh = value;
snr.flag |= SETMASK(UNR_THRESH);
break;
case LCR_THRESH:
if (((snr.flag & GETMASK(LNR_THRESH)) && (value < snr.lnr_thresh)) ||
((snr.flag & GETMASK(LNC_THRESH)) && (value > snr.lnc_thresh)) ||
((snr.flag & GETMASK(UNC_THRESH)) && (value > snr.unc_thresh)) ||
((snr.flag & GETMASK(UCR_THRESH)) && (value > snr.ucr_thresh)) ||
((snr.flag & GETMASK(UNR_THRESH)) && (value > snr.unr_thresh))) {
return -1;
}
snr.lcr_thresh = value;
snr.flag |= SETMASK(LCR_THRESH);
break;
case LNC_THRESH:
if (((snr.flag & GETMASK(LNR_THRESH)) && (value < snr.lnr_thresh)) ||
((snr.flag & GETMASK(LCR_THRESH)) && (value < snr.lcr_thresh)) ||
((snr.flag & GETMASK(UNC_THRESH)) && (value > snr.unc_thresh)) ||
((snr.flag & GETMASK(UCR_THRESH)) && (value > snr.ucr_thresh)) ||
((snr.flag & GETMASK(UNR_THRESH)) && (value > snr.unr_thresh))) {
return -1;
}
snr.lnc_thresh = value;
snr.flag |= SETMASK(LNC_THRESH);
break;
case LNR_THRESH:
if (((snr.flag & GETMASK(LCR_THRESH)) && (value > snr.lcr_thresh)) ||
((snr.flag & GETMASK(LNC_THRESH)) && (value > snr.lnc_thresh)) ||
((snr.flag & GETMASK(UNC_THRESH)) && (value > snr.unc_thresh)) ||
((snr.flag & GETMASK(UCR_THRESH)) && (value > snr.ucr_thresh)) ||
((snr.flag & GETMASK(UNR_THRESH)) && (value > snr.unr_thresh))) {
return -1;
}
snr.lnr_thresh = value;
snr.flag |= SETMASK(LNR_THRESH);
break;
default:
syslog(LOG_WARNING, "%s Incorrect sensor threshold type",__func__);
return -1;
}
ret = pal_copy_thresh_to_file(fru, sensor_num, &snr);
if (ret < 0) {
printf("fail to set threshold file for %s\n", fru_name);
return ret;
}
// Create reinit file
memset(fpath, 0, sizeof(fpath));
sprintf(fpath, THRESHOLD_RE_FLAG, fru_name);
sprintf(cmd,"touch %s",fpath);
if (system(cmd) != 0) {
syslog(LOG_ERR, "%s failed", cmd);
}
return 0;
}
void __attribute__((weak))
pal_get_me_name(uint8_t fru, char *target_name) {
strcpy(target_name, "ME");
return;
}
int __attribute__((weak))
pal_ignore_thresh(uint8_t fru, uint8_t snr_num, uint8_t thresh){
return 0;
}
void __attribute__((weak))
pal_sensor_assert_handle(uint8_t fru, uint8_t snr_num, float val, uint8_t thresh)
{
return;
}
void __attribute__((weak))
pal_sensor_deassert_handle(uint8_t fru, uint8_t snr_num, float val, uint8_t thresh)
{
return;
}
int __attribute__((weak))
pal_get_sensor_util_timeout(uint8_t fru) {
return 4;
}