summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/recipes-connectivity/openssh/openssh_%.bbappend (renamed from common/recipes-connectivity/openssh/openssh_6.5%.bbappend)0
-rw-r--r--common/recipes-core/consoled/files/consoled.c8
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp390
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp4
-rw-r--r--common/recipes-core/fruid/files/fruid-util.c176
-rw-r--r--common/recipes-core/healthd/files/Makefile26
-rw-r--r--common/recipes-core/healthd/files/healthd.c77
-rw-r--r--common/recipes-core/healthd/files/setup-healthd.sh34
-rw-r--r--common/recipes-core/healthd/healthd_0.1.bb42
-rw-r--r--common/recipes-core/i2c-tools/i2c-tools_3.1.1.bb38
-rw-r--r--common/recipes-core/init-ifupdown/files/dhcpv6_down27
-rw-r--r--common/recipes-core/init-ifupdown/files/dhcpv6_up28
-rw-r--r--common/recipes-core/init-ifupdown/init-ifupdown_%.bbappend16
-rw-r--r--common/recipes-core/ipmbd/files/ipmbd.c136
-rw-r--r--common/recipes-core/ipmid/files/ipmid.c270
-rw-r--r--common/recipes-core/ipmid/files/sdr.c18
-rw-r--r--common/recipes-core/ipmid/files/sel.c306
-rw-r--r--common/recipes-core/ipmid/files/sel.h18
-rw-r--r--common/recipes-core/log-util/files/lib_pal.py31
-rw-r--r--common/recipes-core/log-util/files/log-util.py94
-rw-r--r--common/recipes-core/log-util/log-util_0.1.bb57
-rw-r--r--common/recipes-core/power-util/files/power-util.c118
-rw-r--r--common/recipes-core/python/python_2.7.9.bbappend21
-rw-r--r--common/recipes-core/sensor-mon/files/sensord.c903
-rw-r--r--common/recipes-core/sensor-mon/sensor-mon_0.1.bb4
-rw-r--r--common/recipes-core/sensor-util/files/Makefile2
-rw-r--r--common/recipes-core/sensor-util/files/sensor-util.c137
-rw-r--r--common/recipes-core/sensor-util/sensor-util_0.1.bb2
-rw-r--r--common/recipes-lib/fruid/files/fruid.c34
-rw-r--r--common/recipes-lib/ipmb/files/ipmb.c27
-rw-r--r--common/recipes-lib/ipmb/files/ipmb.h5
-rw-r--r--common/recipes-lib/ipmi/files/ipmi.c23
-rw-r--r--common/recipes-lib/ipmi/files/ipmi.h14
-rw-r--r--common/recipes-lib/sdr/files/Makefile2
-rw-r--r--common/recipes-lib/sdr/files/sdr.c383
-rw-r--r--common/recipes-lib/sdr/files/sdr.h38
-rw-r--r--common/recipes-lib/sdr/libsdr_0.1.bb2
-rw-r--r--common/recipes-rest/cherryPy/cherryPy_3.8.0.bb14
-rw-r--r--common/recipes-rest/rest-api/files/node_server.py7
-rw-r--r--common/recipes-rest/rest-api/files/pal.py8
-rw-r--r--common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py76
-rw-r--r--common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py34
-rw-r--r--common/recipes-utils/openbmc-gpio/files/setup.py5
-rw-r--r--common/recipes-utils/openbmc-gpio/files/setup_board.py23
-rw-r--r--common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb13
-rw-r--r--common/recipes-utils/spatula/files/setup-spatula.sh2
-rw-r--r--common/recipes-utils/spatula/files/spatula_wrapper.py87
47 files changed, 2474 insertions, 1306 deletions
diff --git a/common/recipes-connectivity/openssh/openssh_6.5%.bbappend b/common/recipes-connectivity/openssh/openssh_%.bbappend
index 60b164b..60b164b 100644
--- a/common/recipes-connectivity/openssh/openssh_6.5%.bbappend
+++ b/common/recipes-connectivity/openssh/openssh_%.bbappend
diff --git a/common/recipes-core/consoled/files/consoled.c b/common/recipes-core/consoled/files/consoled.c
index 9f17e31..b15011e 100644
--- a/common/recipes-core/consoled/files/consoled.c
+++ b/common/recipes-core/consoled/files/consoled.c
@@ -49,7 +49,7 @@ write_data(int file, char *buf, int len, char *fname) {
len -= wlen;
tbuf = tbuf + wlen;
} else {
- syslog(LOG_ALERT, "write_data: write() failed to file %s | errno: %d",
+ syslog(LOG_WARNING, "write_data: write() failed to file %s | errno: %d",
fname, errno);
return;
}
@@ -124,7 +124,7 @@ run_console(char* fru_name, int term) {
(O_RDONLY | O_NOCTTY | O_NONBLOCK);
if ((tty = open(devtty, flags)) < 0) {
- syslog(LOG_ALERT, "Cannot open the file %s", devtty);
+ syslog(LOG_WARNING, "Cannot open the file %s", devtty);
exit(-1);
}
fcntl(tty, F_SETFL, O_RDWR);
@@ -144,7 +144,7 @@ run_console(char* fru_name, int term) {
sprintf(old_bfname, "/tmp/consoled_%s_log-old", fru_name);
sprintf(bfname, "/tmp/consoled_%s_log", fru_name);
if ((buf_fd = open(bfname, O_RDWR | O_APPEND | O_CREAT, 0666)) < 0) {
- syslog(LOG_ALERT, "Cannot open the file %s", bfname);
+ syslog(LOG_WARNING, "Cannot open the file %s", bfname);
exit(-1);
}
@@ -213,7 +213,7 @@ run_console(char* fru_name, int term) {
remove(old_bfname);
rename(bfname, old_bfname);
if ((buf_fd = open(bfname, O_RDWR | O_APPEND | O_CREAT, 0666)) < 0) {
- syslog(LOG_ALERT, "Cannot open the file %s", bfname);
+ syslog(LOG_WARNING, "Cannot open the file %s", bfname);
exit(-1);
}
nline = 0;
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp b/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp
index 49c6f6b..ccfbdb1 100644
--- a/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp
@@ -40,11 +40,14 @@
/* Yeah, the file ends in .cpp, but it's a C program. Deal. */
-#if !defined(CONFIG_YOSEMITE) && !defined(CONFIG_WEDGE)
+/* XXX: Both CONFIG_WEDGE and CONFIG_WEDGE100 are defined for Wedge100 */
+
+#if !defined(CONFIG_YOSEMITE) && !defined(CONFIG_WEDGE) && \
+ !defined(CONFIG_WEDGE100)
#error "No hardware platform defined!"
#endif
#if defined(CONFIG_YOSEMITE) && defined(CONFIG_WEDGE)
-#error "Both hardware platform defined!"
+#error "Two hardware platforms defined!"
#endif
#include <stdio.h>
@@ -54,12 +57,12 @@
#include <errno.h>
#include <signal.h>
#include <syslog.h>
-#ifdef CONFIG_YOSEMITE
+#if defined(CONFIG_YOSEMITE)
#include <openbmc/ipmi.h>
#include <facebook/bic.h>
#include <facebook/yosemite_sensor.h>
#endif
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
#include <facebook/wedge_eeprom.h>
#endif
@@ -67,23 +70,15 @@
/* Sensor definitions */
-#ifdef CONFIG_WEDGE
-#define INTERNAL_TEMPS(x) ((x) * 1000) // stored a C * 1000
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
+#define INTERNAL_TEMPS(x) ((x) * 1000) // stored as C * 1000
#define EXTERNAL_TEMPS(x) ((x) / 1000)
-#elif CONFIG_YOSEMITE
+#elif defined(CONFIG_YOSEMITE)
#define INTERNAL_TEMPS(x) (x)
#define EXTERNAL_TEMPS(x) (x)
#define TOTAL_1S_SERVERS 4
#endif
-#define I2C_BUS_3_DIR "/sys/class/i2c-adapter/i2c-3/"
-#define I2C_BUS_4_DIR "/sys/class/i2c-adapter/i2c-4/"
-
-#define INTAKE_TEMP_DEVICE I2C_BUS_3_DIR "3-0048"
-#define T2_TEMP_DEVICE I2C_BUS_3_DIR "3-0049"
-#define EXHAUST_TEMP_DEVICE I2C_BUS_3_DIR "3-004a"
-#define USERVER_TEMP_DEVICE I2C_BUS_4_DIR "4-0040"
-
/*
* The sensor for the uServer CPU is not on the CPU itself, so it reads
* a little low. We are special casing this, but we should obviously
@@ -91,10 +86,10 @@
* the entire configuration. JSON file?
*/
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
#define USERVER_TEMP_FUDGE INTERNAL_TEMPS(10)
#else
-#define USERVER_TEMP_FUDGE INTERNAL_TEMPS(1)
+#define USERVER_TEMP_FUDGE INTERNAL_TEMPS(0)
#endif
#define BAD_TEMP INTERNAL_TEMPS(-60)
@@ -104,25 +99,47 @@
#define FAN_SHUTDOWN_THRESHOLD 20 /* How long fans can be failed before */
/* we just shut down the whole thing. */
+#if defined(CONFIG_WEDGE100)
+#define PWM_DIR "/sys/bus/i2c/drivers/fancpld/8-0033/"
-#define PWM_DIR "/sys/devices/platform/ast_pwm_tacho.0"
+#define PWM_UNIT_MAX 31
-#define PWM_UNIT_MAX 96
+#define LM75_DIR "/sys/bus/i2c/drivers/lm75/"
+#define PANTHER_PLUS_DIR "/sys/bus/i2c/drivers/panther_plus/"
-#define LARGEST_DEVICE_NAME 120
+#define INTAKE_TEMP_DEVICE LM75_DIR "3-0048"
+#define CHIP_TEMP_DEVICE LM75_DIR "3-004b"
+#define EXHAUST_TEMP_DEVICE LM75_DIR "3-0048"
+#define USERVER_TEMP_DEVICE PANTHER_PLUS_DIR "4-0040"
-#define GPIO_USERVER_POWER_DIRECTION "/sys/class/gpio/gpio25/direction"
-#define GPIO_USERVER_POWER "/sys/class/gpio/gpio25/value"
-#define GPIO_T2_POWER_DIRECTION "/tmp/gpionames/T2_POWER_UP/direction"
-#define GPIO_T2_POWER "/tmp/gpionames/T2_POWER_UP/value"
+#define FAN_READ_RPM_FORMAT "fan%d_input"
+
+#define FAN0_LED PWM_DIR "fantray1_led_ctrl"
+#define FAN1_LED PWM_DIR "fantray2_led_ctrl"
+#define FAN2_LED PWM_DIR "fantray3_led_ctrl"
+#define FAN3_LED PWM_DIR "fantray4_led_ctrl"
+#define FAN4_LED PWM_DIR "fantray5_led_ctrl"
+
+#define FAN_LED_BLUE "0x1"
+#define FAN_LED_RED "0x2"
+
+#define MAIN_POWER "/sys/bus/i2c/drivers/syscpld/12-0031/pwr_main_n"
+#define USERVER_POWER "/sys/bus/i2c/drivers/syscpld/12-0031/pwr_usrv_en"
+
+#elif defined(CONFIG_WEDGE)
+#define I2C_BUS_3_DIR "/sys/class/i2c-adapter/i2c-3/"
+#define I2C_BUS_4_DIR "/sys/class/i2c-adapter/i2c-4/"
+
+#define INTAKE_TEMP_DEVICE I2C_BUS_3_DIR "3-0048"
+#define CHIP_TEMP_DEVICE I2C_BUS_3_DIR "3-0049"
+#define EXHAUST_TEMP_DEVICE I2C_BUS_3_DIR "3-004a"
+#define USERVER_TEMP_DEVICE I2C_BUS_4_DIR "4-0040"
-#define GPIO_FAN0_LED "/sys/class/gpio/gpio53/value"
-#define GPIO_FAN1_LED "/sys/class/gpio/gpio54/value"
-#define GPIO_FAN2_LED "/sys/class/gpio/gpio55/value"
-#define GPIO_FAN3_LED "/sys/class/gpio/gpio72/value"
-const char *fan_led[] = {GPIO_FAN0_LED, GPIO_FAN1_LED,
- GPIO_FAN2_LED, GPIO_FAN3_LED};
+#define FAN0_LED "/sys/class/gpio/gpio53/value"
+#define FAN1_LED "/sys/class/gpio/gpio54/value"
+#define FAN2_LED "/sys/class/gpio/gpio55/value"
+#define FAN3_LED "/sys/class/gpio/gpio72/value"
#define FAN_LED_RED "0"
#define FAN_LED_BLUE "1"
@@ -142,13 +159,45 @@ const char *fan_led[] = {GPIO_FAN0_LED, GPIO_FAN1_LED,
#define REV_ID_NEW_BOARD_ID 3
#define GPIO_BOARD_ID_START_NEW 166
+#elif defined(CONFIG_YOSEMITE)
+#define FAN_LED_RED "0"
+#define FAN_LED_BLUE "1"
+#endif
+
+#if (defined(CONFIG_YOSEMITE) || defined(CONFIG_WEDGE)) && \
+ !defined(CONFIG_WEDGE100)
+#define PWM_DIR "/sys/devices/platform/ast_pwm_tacho.0"
+
+#define PWM_UNIT_MAX 96
+#define FAN_READ_RPM_FORMAT "tacho%d_rpm"
+
+#define GPIO_USERVER_POWER_DIRECTION "/sys/class/gpio/gpio25/direction"
+#define GPIO_USERVER_POWER "/sys/class/gpio/gpio25/value"
+#define GPIO_T2_POWER_DIRECTION "/tmp/gpionames/T2_POWER_UP/direction"
+#define GPIO_T2_POWER "/tmp/gpionames/T2_POWER_UP/value"
+#endif
+
+#define LARGEST_DEVICE_NAME 120
+
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
+const char *fan_led[] = {FAN0_LED, FAN1_LED, FAN2_LED, FAN3_LED,
+#if defined(CONFIG_WEDGE100)
+ FAN4_LED,
+#endif
+};
+#endif
+
#define REPORT_TEMP 720 /* Report temp every so many cycles */
/* Sensor limits and tuning parameters */
#define INTAKE_LIMIT INTERNAL_TEMPS(60)
-#define T2_LIMIT INTERNAL_TEMPS(80)
+#define SWITCH_LIMIT INTERNAL_TEMPS(80)
+#if defined(CONFIG_YOSEMITE)
+#define USERVER_LIMIT INTERNAL_TEMPS(110)
+#else
#define USERVER_LIMIT INTERNAL_TEMPS(90)
+#endif
#define TEMP_TOP INTERNAL_TEMPS(70)
#define TEMP_BOTTOM INTERNAL_TEMPS(40)
@@ -165,7 +214,11 @@ const char *fan_led[] = {GPIO_FAN0_LED, GPIO_FAN1_LED,
#define WEDGE_FAN_LOW 35
#define WEDGE_FAN_MEDIUM 50
#define WEDGE_FAN_HIGH 70
+#if defined(CONFIG_WEDGE100)
+#define WEDGE_FAN_MAX 100
+#else
#define WEDGE_FAN_MAX 99
+#endif
#define SIXPACK_FAN_LOW 35
#define SIXPACK_FAN_MEDIUM 55
@@ -177,19 +230,28 @@ const char *fan_led[] = {GPIO_FAN0_LED, GPIO_FAN1_LED,
* RPM measuring and PWM setting, naturally. Doh.
*/
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE100)
+int fan_to_rpm_map[] = {1, 3, 5, 7, 9};
+int fan_to_pwm_map[] = {1, 2, 3, 4, 5};
+#define FANS 5
+// Tacho offset between front and rear fans:
+#define REAR_FAN_OFFSET 1
+#define BACK_TO_BACK_FANS
+
+#elif defined(CONFIG_WEDGE)
int fan_to_rpm_map[] = {3, 2, 0, 1};
int fan_to_pwm_map[] = {7, 6, 0, 1};
#define FANS 4
// Tacho offset between front and rear fans:
#define REAR_FAN_OFFSET 4
#define BACK_TO_BACK_FANS
-#else
+#elif defined(CONFIG_YOSEMITE)
int fan_to_rpm_map[] = {0, 1};
int fan_to_pwm_map[] = {0, 1};
#define FANS 2
// Tacho offset between front and rear fans:
#define REAR_FAN_OFFSET 1
+
#endif
@@ -205,11 +267,49 @@ int fan_to_pwm_map[] = {0, 1};
*/
struct rpm_to_pct_map {
- ushort pct;
- ushort rpm;
+ uint pct;
+ uint rpm;
};
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE100)
+struct rpm_to_pct_map rpm_front_map[] = {{20, 4200},
+ {25, 5550},
+ {30, 6180},
+ {35, 7440},
+ {40, 8100},
+ {45, 9300},
+ {50, 10410},
+ {55, 10920},
+ {60, 11910},
+ {65, 12360},
+ {70, 13260},
+ {75, 14010},
+ {80, 14340},
+ {85, 15090},
+ {90, 15420},
+ {95, 15960},
+ {100, 16200}};
+#define FRONT_MAP_SIZE (sizeof(rpm_front_map) / sizeof(struct rpm_to_pct_map))
+
+struct rpm_to_pct_map rpm_rear_map[] = {{20, 2130},
+ {25, 3180},
+ {30, 3690},
+ {35, 4620},
+ {40, 5130},
+ {45, 6120},
+ {50, 7050},
+ {55, 7560},
+ {60, 8580},
+ {65, 9180},
+ {70, 10230},
+ {75, 11280},
+ {80, 11820},
+ {85, 12870},
+ {90, 13350},
+ {95, 14370},
+ {100, 14850}};
+#define REAR_MAP_SIZE (sizeof(rpm_rear_map) / sizeof(struct rpm_to_pct_map))
+#elif defined(CONFIG_WEDGE)
struct rpm_to_pct_map rpm_front_map[] = {{30, 6150},
{35, 7208},
{40, 8195},
@@ -243,22 +343,21 @@ struct rpm_to_pct_map rpm_rear_map[] = {{30, 3911},
{95, 15516},
{100, 15897}};
#define REAR_MAP_SIZE (sizeof(rpm_rear_map) / sizeof(struct rpm_to_pct_map))
-#else
-struct rpm_to_pct_map rpm_map[] = {{30, 3413},
- {35, 3859},
- {40, 4305},
- {45, 4686},
- {50, 5032},
- {55, 5432},
- {60, 5991},
- {65, 6460},
- {70, 6927},
- {75, 7379},
- {80, 7733},
- {85, 8156},
- {90, 8599},
- {95, 9049},
- {100, 9265}};
+#elif defined(CONFIG_YOSEMITE)
+
+/* XXX: Note that 0% is far from 0 RPM. */
+struct rpm_to_pct_map rpm_map[] = {{0, 989},
+ {10, 1654},
+ {20, 2650},
+ {30, 3434},
+ {40, 4318},
+ {50, 5202},
+ {60, 5969},
+ {70, 6869},
+ {80, 7604},
+ {90, 8525},
+ {100, 9325}};
+
struct rpm_to_pct_map *rpm_front_map = rpm_map;
struct rpm_to_pct_map *rpm_rear_map = rpm_map;
#define MAP_SIZE (sizeof(rpm_map) / sizeof(struct rpm_to_pct_map))
@@ -267,6 +366,50 @@ struct rpm_to_pct_map *rpm_rear_map = rpm_map;
#endif
+/*
+ * Mappings from temperatures recorded from sensors to fan speeds;
+ * note that in some cases, we want to be able to look at offsets
+ * from the CPU temperature margin rather than an absolute temperature,
+ * so we use ints.
+ */
+
+struct temp_to_pct_map {
+ int temp;
+ unsigned speed;
+};
+
+#if defined(CONFIG_YOSEMITE)
+struct temp_to_pct_map intake_map[] = {{25, 15},
+ {27, 16},
+ {29, 17},
+ {31, 18},
+ {33, 19},
+ {35, 20},
+ {37, 21},
+ {39, 22},
+ {41, 23},
+ {43, 24},
+ {45, 25}};
+#define INTAKE_MAP_SIZE (sizeof(intake_map) / sizeof(struct temp_to_pct_map))
+
+struct temp_to_pct_map cpu_map[] = {{-28, 10},
+ {-26, 20},
+ {-24, 25},
+ {-22, 30},
+ {-20, 35},
+ {-18, 40},
+ {-16, 45},
+ {-14, 50},
+ {-12, 55},
+ {-10, 60},
+ {-8, 65},
+ {-6, 70},
+ {-4, 80},
+ {-2, 100}};
+#define CPU_MAP_SIZE (sizeof(cpu_map) / sizeof(struct temp_to_pct_map))
+#endif
+
+
#define FAN_FAILURE_OFFSET 30
int fan_low = WEDGE_FAN_LOW;
@@ -355,7 +498,7 @@ int write_device(const char *device, const char *value) {
}
}
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
int read_temp(const char *device, int *value) {
char full_name[LARGEST_DEVICE_NAME + 1];
@@ -365,7 +508,9 @@ int read_temp(const char *device, int *value) {
full_name, LARGEST_DEVICE_NAME, "%s/temp1_input", device);
return read_device(full_name, value);
}
+#endif
+#if defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
int read_gpio_value(const int id, const char *device, int *value) {
char full_name[LARGEST_DEVICE_NAME];
@@ -448,7 +593,7 @@ int read_fan_value(const int fan, const char *device, int *value) {
char full_name[LARGEST_DEVICE_NAME];
snprintf(device_name, LARGEST_DEVICE_NAME, device, fan);
- snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", PWM_DIR, device_name);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", PWM_DIR,device_name);
return read_device(full_name, value);
}
@@ -512,11 +657,11 @@ int fan_speed_okay(const int fan, const int speed, const int slop) {
real_fan = fan_to_rpm_map[fan];
front_fan = 0;
- read_fan_value(real_fan, "tacho%d_rpm", &front_fan);
+ read_fan_value(real_fan, FAN_READ_RPM_FORMAT, &front_fan);
front_pct = fan_rpm_to_pct(rpm_front_map, FRONT_MAP_SIZE, front_fan);
#ifdef BACK_TO_BACK_FANS
rear_fan = 0;
- read_fan_value(real_fan + REAR_FAN_OFFSET, "tacho%d_rpm", &rear_fan);
+ read_fan_value(real_fan + REAR_FAN_OFFSET, FAN_READ_RPM_FORMAT, &rear_fan);
rear_pct = fan_rpm_to_pct(rpm_rear_map, REAR_MAP_SIZE, rear_fan);
#endif
@@ -539,7 +684,7 @@ int fan_speed_okay(const int fan, const int speed, const int slop) {
#endif
if (!okay || verbose) {
- syslog(!okay ? LOG_ALERT : LOG_INFO,
+ syslog(!okay ? LOG_WARNING : LOG_INFO,
#ifdef BACK_TO_BACK_FANS
"fan %d rear %d (%d%%), front %d (%d%%), expected %d",
#else
@@ -570,11 +715,19 @@ int write_fan_speed(const int fan, const int value) {
int real_fan = fan_to_pwm_map[fan];
if (value == 0) {
+#if defined(CONFIG_WEDGE100)
+ return write_fan_value(real_fan, "fantray%d_pwm", 0);
+#else
return write_fan_value(real_fan, "pwm%d_en", 0);
+#endif
} else {
int unit = value * PWM_UNIT_MAX / 100;
int status;
+#if defined(CONFIG_WEDGE100)
+ // Note that PWM for Wedge100 is in 32nds of a cycle
+ return write_fan_value(real_fan, "fantray%d_pwm", unit);
+#else
if (unit == PWM_UNIT_MAX)
unit = 0;
@@ -584,14 +737,25 @@ int write_fan_speed(const int fan, const int value) {
(status = write_fan_value(real_fan, "pwm%d_en", 1)) != 0) {
return status;
}
+#endif
+ }
+}
+
+#if defined(CONFIG_YOSEMITE)
+int temp_to_fan_speed(int temp, struct temp_to_pct_map *map, int map_size) {
+ int i = map_size - 1;
+
+ while (i > 0 && temp < map[i].temp) {
+ --i;
}
+ return map[i].speed;
}
+#endif
/* Set up fan LEDs */
-int write_fan_led(const int fan, const char *color)
-{
-#ifdef CONFIG_WEDGE
+int write_fan_led(const int fan, const char *color) {
+#if defined(CONFIG_WEDGE100) || defined(CONFIG_WEDGE)
return write_device(fan_led[fan], color);
#else
return 0;
@@ -605,9 +769,14 @@ int server_shutdown(const char *why) {
}
syslog(LOG_EMERG, "Shutting down: %s", why);
+#if defined(CONFIG_WEDGE100)
+ write_device(USERVER_POWER, "0");
+ sleep(5);
+ write_device(MAIN_POWER, "0");
+#endif
+#if defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
write_device(GPIO_USERVER_POWER_DIRECTION, "out");
write_device(GPIO_USERVER_POWER, "0");
-#ifdef CONFIG_WEDGE
/*
* Putting T2 in reset generates a non-maskable interrupt to uS,
* the kernel running on uS might panic depending on its version.
@@ -627,7 +796,6 @@ int server_shutdown(const char *why) {
system("rmmod adm1275");
system("i2cset -y 12 0x10 0x01 00");
}
-
#else
// TODO(7088822): try throttling, then shutting down server.
syslog(LOG_EMERG, "Need to implement actual shutdown!\n");
@@ -654,7 +822,7 @@ void fand_interrupt(int sig)
write_fan_speed(fan + fan_offset, fan_max);
}
- syslog(LOG_ALERT, "Shutting down fand on signal %s", strsignal(sig));
+ syslog(LOG_WARNING, "Shutting down fand on signal %s", strsignal(sig));
if (sig == SIGUSR1) {
stop_watchdog();
}
@@ -664,10 +832,10 @@ void fand_interrupt(int sig)
int main(int argc, char **argv) {
/* Sensor values */
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE)
int intake_temp;
int exhaust_temp;
- int t2_temp;
+ int switch_temp;
int userver_temp;
#else
float intake_temp;
@@ -702,7 +870,7 @@ int main(int argc, char **argv) {
openlog("fand", LOG_CONS, LOG_DAEMON);
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
if (is_two_fan_board(false)) {
/* Alternate, two fan configuration */
total_fans = 2;
@@ -779,11 +947,25 @@ int main(int argc, char **argv) {
write_fan_led(fan + fan_offset, FAN_LED_BLUE);
}
-#ifdef CONFIG_YOSEMITE
+#if defined(CONFIG_YOSEMITE)
/* Ensure that we can read from sensors before proceeding. */
- while (yosemite_sensor_read(1, BIC_SENSOR_SOC_TEMP, &userver_temp))
- syslog(LOG_DEBUG, "Failed reading of SOC_TEMP.");
+ int found = 0;
+ userver_temp = 100;
+ while (!found) {
+ for (int node = 1; node <= TOTAL_1S_SERVERS && !found; node++) {
+ if (!yosemite_sensor_read(node, BIC_SENSOR_SOC_THERM_MARGIN,
+ &userver_temp) &&
+ userver_temp < 0) {
+ syslog(LOG_DEBUG, "SOC_THERM_MARGIN first valid read of %f.",
+ userver_temp);
+ found = 1;
+ }
+ sleep(5);
+ }
+ // XXX: Will it ever be a problem that we don't exit this until
+ // we see a valid value?
+ }
#endif
/* Start watchdog in manual mode */
@@ -801,10 +983,10 @@ int main(int argc, char **argv) {
/* Read sensors */
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
read_temp(INTAKE_TEMP_DEVICE, &intake_temp);
read_temp(EXHAUST_TEMP_DEVICE, &exhaust_temp);
- read_temp(T2_TEMP_DEVICE, &t2_temp);
+ read_temp(CHIP_TEMP_DEVICE, &switch_temp);
read_temp(USERVER_TEMP_DEVICE, &userver_temp);
/*
@@ -813,13 +995,13 @@ int main(int argc, char **argv) {
*/
if ((intake_temp == BAD_TEMP || exhaust_temp == BAD_TEMP ||
- t2_temp == BAD_TEMP)) {
+ switch_temp == BAD_TEMP)) {
bad_reads++;
}
#else
- userver_temp = BAD_TEMP;
- if (yosemite_sensor_read(1, SP_SENSOR_INLET_TEMP, &intake_temp) ||
- yosemite_sensor_read(1, SP_SENSOR_OUTLET_TEMP, &exhaust_temp))
+ intake_temp = exhaust_temp = userver_temp = BAD_TEMP;
+ if (yosemite_sensor_read(FRU_SPB, SP_SENSOR_INLET_TEMP, &intake_temp) ||
+ yosemite_sensor_read(FRU_SPB, SP_SENSOR_OUTLET_TEMP, &exhaust_temp))
bad_reads++;
/*
@@ -829,11 +1011,15 @@ int main(int argc, char **argv) {
*/
for (int node = 1; node <= TOTAL_1S_SERVERS; node++) {
float new_temp;
- if (!yosemite_sensor_read(node, BIC_SENSOR_SOC_TEMP, &new_temp)) {
+ if (!yosemite_sensor_read(node, BIC_SENSOR_SOC_THERM_MARGIN,
+ &new_temp)) {
if (userver_temp < new_temp) {
userver_temp = new_temp;
}
}
+
+ // Since the yosemite_sensor_read() times out after 8secs, keep WDT from expiring
+ kick_watchdog();
}
#endif
@@ -843,7 +1029,7 @@ int main(int argc, char **argv) {
if (log_count++ % report_temp == 0) {
syslog(LOG_DEBUG,
-#ifdef CONFIG_WEDGE
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
"Temp intake %d, t2 %d, "
" userver %d, exhaust %d, "
"fan speed %d, speed changes %d",
@@ -852,8 +1038,8 @@ int main(int argc, char **argv) {
"fan speed %d, speed changes %d",
#endif
intake_temp,
-#ifdef CONFIG_WEDGE
- t2_temp,
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
+ switch_temp,
#endif
userver_temp,
exhaust_temp,
@@ -867,8 +1053,8 @@ int main(int argc, char **argv) {
server_shutdown("Intake temp limit reached");
}
-#ifdef CONFIG_WEDGE
- if (t2_temp > T2_LIMIT) {
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
+ if (switch_temp > SWITCH_LIMIT) {
server_shutdown("T2 temp limit reached");
}
#endif
@@ -885,20 +1071,28 @@ int main(int argc, char **argv) {
* as well.
*/
-#ifdef CONFIG_WEDGE
- if (t2_temp > userver_temp + USERVER_TEMP_FUDGE) {
- max_temp = t2_temp;
+#if defined(CONFIG_YOSEMITE)
+ /* Use tables to lookup the new fan speed for Yosemite. */
+
+ int intake_speed = temp_to_fan_speed(intake_temp, intake_map,
+ INTAKE_MAP_SIZE);
+ int cpu_speed = temp_to_fan_speed(userver_temp, cpu_map, CPU_MAP_SIZE);
+
+ if (fan_speed == fan_max && fan_failure != 0) {
+ /* Don't change a thing */
+ } else if (intake_speed > cpu_speed) {
+ fan_speed = intake_speed;
} else {
- max_temp = userver_temp + USERVER_TEMP_FUDGE;
+ fan_speed = cpu_speed;
}
#else
- /* Yosemite could have no servers turned on, so ignore that case. */
- if (userver_temp + USERVER_TEMP_FUDGE > exhaust_temp) {
- max_temp = userver_temp + USERVER_TEMP_FUDGE;
+ /* Other systems use a simpler built-in table to determine fan speed. */
+
+ if (switch_temp > userver_temp + USERVER_TEMP_FUDGE) {
+ max_temp = switch_temp;
} else {
- max_temp = exhaust_temp;
+ max_temp = userver_temp + USERVER_TEMP_FUDGE;
}
-#endif
/*
* If recovering from a fan problem, spin down fans gradually in case
@@ -924,6 +1118,7 @@ int main(int argc, char **argv) {
fan_speed = fan_medium;
}
}
+#endif
/*
* Update fans only if there are no failed ones. If any fans failed
@@ -962,7 +1157,7 @@ int main(int argc, char **argv) {
if (fan_speed_okay(fan + fan_offset, fan_speed, FAN_FAILURE_OFFSET)) {
if (fan_bad[fan] > FAN_FAILURE_THRESHOLD) {
write_fan_led(fan + fan_offset, FAN_LED_BLUE);
- syslog(LOG_NOTICE,
+ syslog(LOG_CRIT,
"Fan %d has recovered",
fan);
}
@@ -982,7 +1177,7 @@ int main(int argc, char **argv) {
if (fan_failure > 0) {
if (prev_fans_bad != fan_failure) {
- syslog(LOG_ALERT, "%d fans failed", fan_failure);
+ syslog(LOG_CRIT, "%d fans failed", fan_failure);
}
/*
@@ -999,6 +1194,15 @@ int main(int argc, char **argv) {
write_fan_speed(fan + fan_offset, fan_speed);
}
+#if defined(CONFIG_WEDGE) || defined(CONFIG_WEDGE100)
+ /*
+ * On Wedge, we want to shut down everything if none of the fans
+ * are visible, since there isn't automatic protection to shut
+ * off the server or switch chip. On other platforms, the CPUs
+ * generating the heat will automatically turn off, so this is
+ * unnecessary.
+ */
+
if (fan_failure == total_fans) {
int count = 0;
for (fan = 0; fan < total_fans; fan++) {
@@ -1009,7 +1213,7 @@ int main(int argc, char **argv) {
server_shutdown("all fans are bad for more than 12 cycles");
}
}
-
+#endif
/*
* Fans can be hot swapped and replaced; in which case the fan daemon
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp b/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp
index ebb390a..f6e5a45 100644
--- a/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp
@@ -100,7 +100,7 @@ int start_watchdog(const int auto_mode) {
while ((status = write(watchdog_dev, WATCHDOG_START_KEY, 1)) == 0
&& errno == EINTR);
pthread_mutex_unlock(&watchdog_lock);
- syslog(LOG_ALERT, "system watchdog already started.\n");
+ syslog(LOG_WARNING, "system watchdog already started.\n");
return 0;
}
@@ -128,7 +128,7 @@ fail:
}
pthread_mutex_unlock(&watchdog_lock);
- syslog(LOG_ALERT, "system watchdog failed to start!\n");
+ syslog(LOG_WARNING, "system watchdog failed to start!\n");
return 0;
}
diff --git a/common/recipes-core/fruid/files/fruid-util.c b/common/recipes-core/fruid/files/fruid-util.c
index 3c8d2e1..d0e19b8 100644
--- a/common/recipes-core/fruid/files/fruid-util.c
+++ b/common/recipes-core/fruid/files/fruid-util.c
@@ -18,11 +18,37 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <string.h>
#include <openbmc/fruid.h>
#include <openbmc/pal.h>
+#define EEPROM_READ 0x1
+#define EEPROM_WRITE 0x2
+#define FRUID_SIZE 256
+
+/* To copy the bin files */
+static int
+copy_file(int out, int in, int bs) {
+
+ ssize_t bytes_rd, bytes_wr;
+ uint64_t tmp[FRUID_SIZE];
+
+ while ((bytes_rd = read(in, tmp, FRUID_SIZE)) > 0) {
+ bytes_wr = write(out, tmp, bytes_rd);
+ if (bytes_wr != bytes_rd) {
+ return errno;
+ }
+ }
+ return 0;
+}
+
/* Print the FRUID in detail */
-void print_fruid_info(fruid_info_t *fruid, const char *name)
+static void
+print_fruid_info(fruid_info_t *fruid, const char *name)
{
/* Print format */
printf("%-27s: %s", "\nFRU Information",
@@ -78,18 +104,27 @@ void get_fruid_info(uint8_t fru, char *path, char* name) {
static int
print_usage() {
- printf("Usage: fruid-util [ %s ]\n", pal_fru_list);
+ printf("Usage: fruid-util [ %s ]\n"
+ "Usage: fruid-util [%s] [--dump | --write ] <file>\n",
+ pal_fru_list, pal_fru_list);
}
/* Utility to just print the FRUID */
int main(int argc, char * argv[]) {
int ret;
+ int rw = 0;
+ int fd_tmpbin;
+ int fd_newbin;
+ int fd_eeprom;
uint8_t fru;
+ char *file_path = NULL;
char path[64] = {0};
+ char eeprom_path[64] = {0};
char name[64] = {0};
+ char command[128] = {0};
- if (argc != 2) {
+ if (argc != 2 && argc != 4) {
print_usage();
exit(-1);
}
@@ -100,8 +135,119 @@ int main(int argc, char * argv[]) {
return ret;
}
- if (fru == 0) {
+ if (fru == 0 && argc > 2) {
+ print_usage();
+ exit(-1);
+ }
+
+ if (argc > 2) {
+ if (!strcmp(argv[2], "--dump")) {
+ rw = EEPROM_READ;
+ file_path = argv[3];
+ } else if (!strcmp(argv[2], "--write")) {
+ rw = EEPROM_WRITE;
+ file_path = argv[3];
+ }
+ }
+
+ // Check if the new eeprom binary file exits.
+ // TODO: Add file size check before adding to the eeprom
+ if (rw == EEPROM_WRITE && (access(file_path, F_OK) == -1)) {
+ print_usage();
+ exit(-1);
+ }
+
+ if (fru != 0) {
+ ret = pal_get_fruid_path(fru, path);
+ if (ret < 0) {
+ return ret;
+ }
+
+ errno = 0;
+
+ /* FRUID BINARY DUMP */
+ if (rw == EEPROM_READ) {
+ fd_tmpbin = open(path, O_RDONLY);
+ if (fd_tmpbin == -1) {
+ syslog(LOG_ERR, "Unable to open the %s file: %s", path, strerror(errno));
+ return errno;
+ }
+
+ fd_newbin = open(file_path, O_WRONLY | O_CREAT, 0644);
+ if (fd_newbin == -1) {
+ syslog(LOG_ERR, "Unable to create %s file: %s", file_path, strerror(errno));
+ return errno;
+ }
+
+ ret = copy_file(fd_newbin, fd_tmpbin, FRUID_SIZE);
+ if (ret < 0) {
+ syslog(LOG_ERR, "copy: write to %s file failed: %s",
+ file_path, strerror(errno));
+ return ret;
+ }
+
+ close(fd_newbin);
+ close(fd_tmpbin);
+
+ } else if (rw == EEPROM_WRITE) {
+
+ /* FRUID BINARY WRITE */
+
+ fd_tmpbin = open(path, O_WRONLY);
+ if (fd_tmpbin == -1) {
+ syslog(LOG_ERR, "Unable to open the %s file: %s", path, strerror(errno));
+ return errno;
+ }
+
+ fd_newbin = open(file_path, O_RDONLY);
+ if (fd_newbin == -1) {
+ syslog(LOG_ERR, "Unable to open the %s file: %s", file_path, strerror(errno));
+ return errno;
+ }
+
+ ret = pal_get_fruid_eeprom_path(fru, eeprom_path);
+ if (ret < 0) {
+ //Can not handle in common, so call pal libray for update
+ pal_fruid_write(fru, file_path);
+ } else {
+ if (access(eeprom_path, F_OK) == -1) {
+ syslog(LOG_ERR, "cannot access the eeprom file : %s for fru %d",
+ eeprom_path, fru);
+ close(fd_newbin);
+ close(fd_tmpbin);
+ return -1;
+ }
+ sprintf(command, "dd if=%s of=%s bs=%d count=1", file_path, eeprom_path, FRUID_SIZE);
+ system(command);
+ }
+
+ ret = copy_file(fd_tmpbin, fd_newbin, FRUID_SIZE);
+ if (ret < 0) {
+ syslog(LOG_ERR, "copy: write to %s file failed: %s",
+ path, strerror(errno));
+ return ret;
+ }
+
+ close(fd_newbin);
+ close(fd_tmpbin);
+
+ } else {
+ /* FRUID PRINT ONE FRU */
+
+ ret = pal_get_fruid_name(fru, name);
+ if (ret < 0) {
+ return ret;
+ }
+
+ get_fruid_info(fru, path, name);
+ }
+
+ } else if (fru == 0) {
+
+ /* FRUID PRINT ALL FRUs */
+
fru = 1;
+
while (fru <= MAX_NUM_FRUS) {
ret = pal_get_fruid_path(fru, path);
if (ret < 0) {
@@ -113,32 +259,10 @@ int main(int argc, char * argv[]) {
return ret;
}
- if (fru == FRU_NIC) {
- printf("fruid-util does not support nic\n");
- exit(-1);
- }
-
get_fruid_info(fru, path, name);
fru++;
}
- } else {
- ret = pal_get_fruid_path(fru, path);
- if (ret < 0) {
- return ret;
- }
-
- ret = pal_get_fruid_name(fru, name);
- if (ret < 0) {
- return ret;
- }
-
- if (fru == FRU_NIC) {
- printf("fruid-util does not support nic\n");
- exit(-1);
- }
-
- get_fruid_info(fru, path, name);
}
return 0;
diff --git a/common/recipes-core/healthd/files/Makefile b/common/recipes-core/healthd/files/Makefile
new file mode 100644
index 0000000..13c0f66
--- /dev/null
+++ b/common/recipes-core/healthd/files/Makefile
@@ -0,0 +1,26 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+all: healthd
+
+healthd: healthd.c
+ $(CC) $(CFLAGS) -pthread -lm -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o healthd
diff --git a/common/recipes-core/healthd/files/healthd.c b/common/recipes-core/healthd/files/healthd.c
new file mode 100644
index 0000000..f02a363
--- /dev/null
+++ b/common/recipes-core/healthd/files/healthd.c
@@ -0,0 +1,77 @@
+/*
+ * healthd
+ *
+ * Copyright 2015-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 <stdlib.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <openbmc/pal.h>
+
+static void
+initilize_all_kv() {
+ pal_set_def_key_value();
+}
+
+static void
+check_all_daemon_health() {
+ while(1) {
+
+ /*
+ * TODO: Check if all the daemons are running fine
+ * TODO: Move the HB led control to this daemon
+ * TODO: Move the watchdog timer to this daemon
+ */
+ sleep(10);
+ }
+}
+
+int
+main(int argc, void **argv) {
+ int dev, rc, pid_file;
+
+ if (argc > 1) {
+ exit(1);
+ }
+
+ pid_file = open("/var/run/healthd.pid", O_CREAT | O_RDWR, 0666);
+ rc = flock(pid_file, LOCK_EX | LOCK_NB);
+ if(rc) {
+ if(EWOULDBLOCK == errno) {
+ printf("Another healthd instance is running...\n");
+ exit(-1);
+ }
+ } else {
+
+ daemon(0,1);
+ openlog("healthd", LOG_CONS, LOG_DAEMON);
+ syslog(LOG_INFO, "healthd: daemon started");
+ }
+
+ initilize_all_kv();
+ check_all_daemon_health();
+ return 0;
+}
+
diff --git a/common/recipes-core/healthd/files/setup-healthd.sh b/common/recipes-core/healthd/files/setup-healthd.sh
new file mode 100644
index 0000000..b64be65
--- /dev/null
+++ b/common/recipes-core/healthd/files/setup-healthd.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+#
+
+### BEGIN INIT INFO
+# Provides: setup-healthd
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Setup sensor monitoring
+### END INIT INFO
+
+echo -n "Setup healthd for BMC "
+
+/usr/local/bin/healthd
+
+echo "done."
diff --git a/common/recipes-core/healthd/healthd_0.1.bb b/common/recipes-core/healthd/healthd_0.1.bb
new file mode 100644
index 0000000..0c4b2e9
--- /dev/null
+++ b/common/recipes-core/healthd/healthd_0.1.bb
@@ -0,0 +1,42 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Health Monitoring Daemon"
+DESCRIPTION = "Daemon for BMC Health monitoring"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://healthd.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://healthd.c \
+ file://setup-healthd.sh \
+ "
+S = "${WORKDIR}"
+
+LDFLAGS =+ " -lpal "
+
+DEPENDS =+ " libpal "
+
+binfiles = "healthd"
+
+pkgdir = "healthd"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 healthd ${dst}/healthd
+ ln -snf ../fbpackages/${pkgdir}/healthd ${bin}/healthd
+
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-healthd.sh ${D}${sysconfdir}/init.d/setup-healthd.sh
+ update-rc.d -r ${D} setup-healthd.sh start 91 5 .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/healthd ${prefix}/local/bin ${sysconfdir} "
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/i2c-tools/i2c-tools_3.1.1.bb b/common/recipes-core/i2c-tools/i2c-tools_3.1.1.bb
deleted file mode 100644
index 6743e3f..0000000
--- a/common/recipes-core/i2c-tools/i2c-tools_3.1.1.bb
+++ /dev/null
@@ -1,38 +0,0 @@
-DESCRIPTION = "i2c tools"
-SECTION = "base"
-LICENSE = "GPLv2"
-LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
-
-SRCREV = "6235"
-SRC_URI = "svn://lm-sensors.org/svn/i2c-tools/branches/;protocol=http;module=i2c-tools-3.1 \
- "
-
-S = "${WORKDIR}/i2c-tools-3.1"
-
-i2ctools = "i2cdetect \
- i2cdump \
- i2cget \
- i2cset \
- "
-
-eepromtools = "eepromer \
- eeprom \
- eeprog \
- "
-
-do_compile() {
- make -C eepromer
- make
-}
-
-do_install() {
- mkdir -p ${D}/${bindir}
- for f in ${i2ctools}; do
- install -m 755 tools/$f ${D}/${bindir}/$f
- done
- for f in ${eepromtools}; do
- install -m 755 eepromer/$f ${D}/${bindir}/$f
- done
-}
-
-FILES_${PN} = "${bindir}"
diff --git a/common/recipes-core/init-ifupdown/files/dhcpv6_down b/common/recipes-core/init-ifupdown/files/dhcpv6_down
new file mode 100644
index 0000000..a44deb4
--- /dev/null
+++ b/common/recipes-core/init-ifupdown/files/dhcpv6_down
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+#
+
+pid="/var/run/dhclient6.${IFACE}.pid"
+
+if [ -f "${pid}" ]; then
+ kill -9 `cat ${pid}` 2>/dev/null
+fi
+
+exit 0
diff --git a/common/recipes-core/init-ifupdown/files/dhcpv6_up b/common/recipes-core/init-ifupdown/files/dhcpv6_up
new file mode 100644
index 0000000..6469b9f
--- /dev/null
+++ b/common/recipes-core/init-ifupdown/files/dhcpv6_up
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+#
+
+# only care about 'eth0' and 'oob' intf
+[ "$IFACE" != "eth0" ] && [ "$IFACE" != "oob" ] && exit 0
+
+pid="/var/run/dhclient6.${IFACE}.pid"
+
+dhclient -6 -nw -pf ${pid} ${IFACE}
+
+exit 0
diff --git a/common/recipes-core/init-ifupdown/init-ifupdown_%.bbappend b/common/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
index 7d74521..e715c27 100644
--- a/common/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
+++ b/common/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
@@ -1,2 +1,18 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://dhcpv6_up \
+ file://dhcpv6_down \
+ "
+
+do_install_append() {
+ # rules to request dhcpv6
+ install -d ${D}/${sysconfdir}/network/if-up.d
+ install -m 755 ${WORKDIR}/dhcpv6_up ${D}${sysconfdir}/network/if-up.d/dhcpv6_up
+ install -d ${D}/${sysconfdir}/network/if-down.d
+ install -m 755 ${WORKDIR}/dhcpv6_down ${D}${sysconfdir}/network/if-down.d/dhcpv6_down
+}
+
+FILES_${PN} += "${sysconfdir}/network/if-up.d/dhcpv6_up \
+ ${sysconfdir}/network/if-down.d/dhcpv6_down \
+ "
diff --git a/common/recipes-core/ipmbd/files/ipmbd.c b/common/recipes-core/ipmbd/files/ipmbd.c
index 5ea5af3..ae40ec7 100644
--- a/common/recipes-core/ipmbd/files/ipmbd.c
+++ b/common/recipes-core/ipmbd/files/ipmbd.c
@@ -73,7 +73,7 @@
#define MQ_IPMB_REQ "/mq_ipmb_req"
#define MQ_IPMB_RES "/mq_ipmb_res"
#define MQ_MAX_MSG_SIZE MAX_BYTES
-#define MQ_MAX_NUM_MSGS 10
+#define MQ_MAX_NUM_MSGS 20
#define SEQ_NUM_MAX 64
@@ -108,6 +108,8 @@ pthread_mutex_t m_seq;
pthread_mutex_t m_i2c;
+static int g_bus_id = 0; // store the i2c bus ID for debug print
+
#ifdef CONFIG_YOSEMITE
// Returns the payload ID from IPMB bus routing
// Slot#1: bus#3, Slot#2: bus#1, Slot#3: bus#7, Slot#4: bus#5
@@ -129,7 +131,7 @@ get_payload_id(uint8_t bus_id) {
payload_id = 3;
break;
default:
- syslog(LOG_ALERT, "get_payload_id: Wrong bus ID\n");
+ syslog(LOG_WARNING, "get_payload_id: Wrong bus ID\n");
break;
}
@@ -138,9 +140,9 @@ get_payload_id(uint8_t bus_id) {
#endif
// Returns an unused seq# from all possible seq#
-static uint8_t
+static int8_t
seq_get_new(void) {
- uint8_t ret = -1;
+ int8_t ret = -1;
uint8_t index;
pthread_mutex_lock(&m_seq);
@@ -183,13 +185,13 @@ i2c_open(uint8_t bus_num) {
snprintf(fn, sizeof(fn), "/dev/i2c-%d", bus_num);
fd = open(fn, O_RDWR);
if (fd == -1) {
- syslog(LOG_ALERT, "Failed to open i2c device %s", fn);
+ syslog(LOG_WARNING, "Failed to open i2c device %s", fn);
return -1;
}
rc = ioctl(fd, I2C_SLAVE, BRIDGE_SLAVE_ADDR);
if (rc < 0) {
- syslog(LOG_ALERT, "Failed to open slave @ address 0x%x", BRIDGE_SLAVE_ADDR);
+ syslog(LOG_WARNING, "Failed to open slave @ address 0x%x", BRIDGE_SLAVE_ADDR);
close(fd);
return -1;
}
@@ -227,7 +229,7 @@ i2c_write(int fd, uint8_t *buf, uint8_t len) {
}
if (rc < 0) {
- syslog(LOG_ALERT, "Failed to do raw io");
+ syslog(LOG_WARNING, "Failed to do raw io");
pthread_mutex_unlock(&m_i2c);
return -1;
}
@@ -249,7 +251,7 @@ i2c_slave_open(uint8_t bus_num) {
snprintf(fn, sizeof(fn), "/dev/i2c-%d", bus_num);
fd = open(fn, O_RDWR);
if (fd == -1) {
- syslog(LOG_ALERT, "Failed to open i2c device %s", fn);
+ syslog(LOG_WARNING, "Failed to open i2c device %s", fn);
return -1;
}
@@ -266,7 +268,7 @@ i2c_slave_open(uint8_t bus_num) {
rc = ioctl(fd, I2C_SLAVE_RDWR, &data);
if (rc < 0) {
- syslog(LOG_ALERT, "Failed to open slave @ address 0x%x", BMC_SLAVE_ADDR);
+ syslog(LOG_WARNING, "Failed to open slave @ address 0x%x", BMC_SLAVE_ADDR);
close(fd);
}
@@ -341,22 +343,22 @@ ipmb_req_handler(void *bus_num) {
// Open the i2c bus for sending response
fd = i2c_open(*bnum);
if (fd < 0) {
- syslog(LOG_ALERT, "i2c_open failure\n");
+ syslog(LOG_WARNING, "i2c_open failure\n");
close(mq);
return NULL;
}
// Loop to process incoming requests
while (1) {
- if ((rlen = mq_receive(mq, rxbuf, MQ_MAX_MSG_SIZE, NULL)) < 0) {
+ if ((rlen = mq_receive(mq, rxbuf, MQ_MAX_MSG_SIZE, NULL)) <= 0) {
sleep(1);
continue;
}
#ifdef DEBUG
- syslog(LOG_ALERT, "Received Request of %d bytes\n", rlen);
+ syslog(LOG_WARNING, "Received Request of %d bytes\n", rlen);
for (i = 0; i < rlen; i++) {
- syslog(LOG_ALERT, "0x%X", rxbuf[i]);
+ syslog(LOG_WARNING, "0x%X", rxbuf[i]);
}
#endif
@@ -407,9 +409,9 @@ ipmb_req_handler(void *bus_num) {
p_ipmb_res->data[tlen-IPMI_RESP_HDR_SIZE];
#ifdef DEBUG
- syslog(LOG_ALERT, "Sending Response of %d bytes\n", tlen+IPMB_HDR_SIZE-1);
+ syslog(LOG_WARNING, "Sending Response of %d bytes\n", tlen+IPMB_HDR_SIZE-1);
for (i = 1; i < tlen+IPMB_HDR_SIZE; i++) {
- syslog(LOG_ALERT, "0x%X:", txbuf[i]);
+ syslog(LOG_WARNING, "0x%X:", txbuf[i]);
}
#endif
@@ -428,45 +430,65 @@ ipmb_res_handler(void *bus_num) {
ipmb_res_t *p_res;
uint8_t index;
char mq_ipmb_res[64] = {0};
+ uint8_t hack = 0;
sprintf(mq_ipmb_res, "%s_%d", MQ_IPMB_RES, *bnum);
// Open the message queue
mq = mq_open(mq_ipmb_res, O_RDONLY);
if (mq == (mqd_t) -1) {
- syslog(LOG_ALERT, "mq_open fails\n");
+ syslog(LOG_WARNING, "mq_open fails\n");
return NULL;
}
// Loop to wait for incomng response messages
while (1) {
- if ((len = mq_receive(mq, buf, MQ_MAX_MSG_SIZE, NULL)) < 0) {
+ if ((len = mq_receive(mq, buf, MQ_MAX_MSG_SIZE, NULL)) <= 0) {
sleep(1);
continue;
}
p_res = (ipmb_res_t *) buf;
+
// Check the seq# of response
index = p_res->seq_lun >> LUN_OFFSET;
+ // TODO: observed the IPMB packets with missing slave address at first byte;
+ // detect and correct them for now, but need fix in i2c driver
+ hack = 0;
+ if ((p_res->res_slave_addr != (BRIDGE_SLAVE_ADDR << 1)) ||
+ (p_res->res_slave_addr == p_res->hdr_cksum)) {
+ index = p_res->res_slave_addr >> LUN_OFFSET;
+ hack = 1;
+ }
// Check if the response is being waited for
pthread_mutex_lock(&m_seq);
if (g_seq.seq[index].in_use) {
// Copy the response to the requester's buffer
- memcpy(g_seq.seq[index].p_buf, buf, len);
- g_seq.seq[index].len = len;
+ if (hack) {
+ // TODO: hack to correct the packet with missing slave address for now
+ *(g_seq.seq[index].p_buf) = (BMC_SLAVE_ADDR << 1);
+ memcpy(g_seq.seq[index].p_buf+1, buf, len);
+ g_seq.seq[index].len = len+1;
+ } else {
+ memcpy(g_seq.seq[index].p_buf, buf, len);
+ g_seq.seq[index].len = len;
+ }
// Wake up the worker thread to receive the response
sem_post(&g_seq.seq[index].s_seq);
+ } else {
+ // Either the IPMB packet is corrupted or arrived late after client exits
+ syslog(LOG_WARNING, "bus: %d, WRONG packet received with seq#%d\n", g_bus_id, index);
}
pthread_mutex_unlock(&m_seq);
#ifdef DEBUG
- syslog(LOG_ALERT, "Received Response of %d bytes\n", len);
+ syslog(LOG_WARNING, "Received Response of %d bytes\n", len);
int i;
for (i = 0; i < len; i++) {
- syslog(LOG_ALERT, "0x%X:", buf[i]);
+ syslog(LOG_WARNING, "0x%X:", buf[i]);
}
#endif
}
@@ -494,7 +516,7 @@ ipmb_rx_handler(void *bus_num) {
// Open the i2c bus as a slave
fd = i2c_slave_open(*bnum);
if (fd < 0) {
- syslog(LOG_ALERT, "i2c_slave_open fails\n");
+ syslog(LOG_WARNING, "i2c_slave_open fails\n");
goto cleanup;
}
@@ -504,13 +526,13 @@ ipmb_rx_handler(void *bus_num) {
// Open the message queues for post processing
mq_req = mq_open(mq_ipmb_req, O_WRONLY);
if (mq_req == (mqd_t) -1) {
- syslog(LOG_ALERT, "mq_open req fails\n");
+ syslog(LOG_WARNING, "mq_open req fails\n");
goto cleanup;
}
mq_res = mq_open(mq_ipmb_res, O_WRONLY);
if (mq_res == (mqd_t) -1) {
- syslog(LOG_ALERT, "mq_open res fails\n");
+ syslog(LOG_WARNING, "mq_open res fails\n");
goto cleanup;
}
@@ -532,9 +554,9 @@ ipmb_rx_handler(void *bus_num) {
tmq = mq_req;
}
// Post message to approriate Queue for further processing
- if (mq_send(tmq, buf, len, 0)) {
- syslog(LOG_ALERT, "mq_send failed\n");
- sleep(1);
+ if (mq_timedsend(tmq, buf, len, 0, &req)) {
+ //syslog(LOG_WARNING, "mq_send failed for queue %d\n", tmq);
+ nanosleep(&req, &rem);
continue;
}
}
@@ -563,7 +585,7 @@ ipmb_handle (int fd, unsigned char *request, unsigned char req_len,
ipmb_req_t *req = (ipmb_req_t *) request;
ipmb_res_t *res = (ipmb_res_t *) response;
- uint8_t index;
+ int8_t index;
struct timespec ts;
// Allocate right sequence Number
@@ -598,12 +620,12 @@ ipmb_handle (int fd, unsigned char *request, unsigned char req_len,
// Wait on semaphore for that sequence Number
clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += TIMEOUT_IPMI;
+ ts.tv_sec += TIMEOUT_IPMB;
int ret;
ret = sem_timedwait(&g_seq.seq[index].s_seq, &ts);
if (ret == -1) {
- syslog(LOG_ALERT, "No response for sequence number: %d\n", index);
+ syslog(LOG_DEBUG, "No response for sequence number: %d\n", index);
*res_len = 0;
}
@@ -628,17 +650,26 @@ void
unsigned char req_buf[MAX_IPMI_MSG_SIZE];
unsigned char res_buf[MAX_IPMI_MSG_SIZE];
unsigned char res_len = 0;
+ struct timeval tv;
+
+ // setup timeout for receving on socket
+ tv.tv_sec = TIMEOUT_IPMB;
+ tv.tv_usec = 0;
+
+ setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
n = recv(sock, req_buf, sizeof(req_buf), 0);
if (n <= 0) {
- syslog(LOG_ALERT, "ipmbd: recv() failed with %d\n", n);
+ syslog(LOG_WARNING, "ipmbd: recv() failed with %d\n", n);
goto conn_cleanup;
}
ipmb_handle(fd, req_buf, n, res_buf, &res_len);
if (send(sock, res_buf, res_len, MSG_NOSIGNAL) < 0) {
- syslog(LOG_ALERT, "ipmbd: send() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "ipmbd: send() failed\n");
+#endif
}
conn_cleanup:
@@ -659,11 +690,12 @@ ipmb_lib_handler(void *bus_num) {
int fd;
uint8_t *bnum = (uint8_t*) bus_num;
char sock_path[20] = {0};
+ int rc = 0;
// Open the i2c bus for sending request
fd = i2c_open(*bnum);
if (fd < 0) {
- syslog(LOG_ALERT, "i2c_open failure\n");
+ syslog(LOG_WARNING, "i2c_open failure\n");
return NULL;
}
@@ -680,7 +712,7 @@ ipmb_lib_handler(void *bus_num) {
if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
{
- syslog(LOG_ALERT, "ipmbd: socket() failed\n");
+ syslog(LOG_WARNING, "ipmbd: socket() failed\n");
exit (1);
}
@@ -692,22 +724,25 @@ ipmb_lib_handler(void *bus_num) {
len = strlen (local.sun_path) + sizeof (local.sun_family);
if (bind (s, (struct sockaddr *) &local, len) == -1)
{
- syslog(LOG_ALERT, "ipmbd: bind() failed\n");
+ syslog(LOG_WARNING, "ipmbd: bind() failed\n");
exit (1);
}
if (listen (s, 5) == -1)
{
- syslog(LOG_ALERT, "ipmbd: listen() failed\n");
+ syslog(LOG_WARNING, "ipmbd: listen() failed\n");
exit (1);
}
while(1) {
int n;
t = sizeof (remote);
+ // TODO: Seen accept() call failure and need further debug
if ((s2 = accept (s, (struct sockaddr *) &remote, &t)) < 0) {
- syslog(LOG_ALERT, "ipmbd: accept() failed\n");
- break;
+ rc = errno;
+ syslog(LOG_WARNING, "ipmbd: accept() failed with ret: %x, errno: %x\n", s2, rc);
+ sleep(5);
+ continue;
}
// Creating a worker thread to handle the request
@@ -718,7 +753,7 @@ ipmb_lib_handler(void *bus_num) {
sfd->fd = fd;
sfd->sock = s2;
if (pthread_create(&tid, NULL, conn_handler, (void*) sfd) < 0) {
- syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ syslog(LOG_WARNING, "ipmbd: pthread_create failed\n");
close(s2);
continue;
}
@@ -743,17 +778,20 @@ main(int argc, char * const argv[]) {
struct mq_attr attr;
char mq_ipmb_req[64] = {0};
char mq_ipmb_res[64] = {0};
+ int rc = 0;
daemon(1, 0);
openlog("ipmbd", LOG_CONS, LOG_DAEMON);
if (argc != 2) {
- syslog(LOG_ALERT, "ipmbd: Usage: ipmbd <bus#>");
+ syslog(LOG_WARNING, "ipmbd: Usage: ipmbd <bus#>");
exit(1);
}
ipmb_bus_num = atoi(argv[1]);
-syslog(LOG_ALERT, "ipmbd: bus#:%d\n", ipmb_bus_num);
+ g_bus_id = ipmb_bus_num;
+
+ syslog(LOG_WARNING, "ipmbd: bus#:%d\n", ipmb_bus_num);
pthread_mutex_init(&m_i2c, NULL);
@@ -769,44 +807,44 @@ syslog(LOG_ALERT, "ipmbd: bus#:%d\n", ipmb_bus_num);
// Remove the MQ if exists
mq_unlink(mq_ipmb_req);
- errno = 0;
mqd_req = mq_open(mq_ipmb_req, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &attr);
if (mqd_req == (mqd_t) -1) {
- syslog(LOG_ALERT, "ipmbd: mq_open request failed errno:%d\n", errno);
+ rc = errno;
+ syslog(LOG_WARNING, "ipmbd: mq_open request failed errno:%d\n", rc);
goto cleanup;
}
// Remove the MQ if exists
mq_unlink(mq_ipmb_res);
- errno = 0;
mqd_res = mq_open(mq_ipmb_res, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &attr);
if (mqd_res == (mqd_t) -1) {
- syslog(LOG_ALERT, "ipmbd: mq_open response failed errno: %d\n", errno);
+ rc = errno;
+ syslog(LOG_WARNING, "ipmbd: mq_open response failed errno: %d\n", rc);
goto cleanup;
}
// Create thread to handle IPMB Requests
if (pthread_create(&tid_req_handler, NULL, ipmb_req_handler, (void*) &ipmb_bus_num) < 0) {
- syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ syslog(LOG_WARNING, "ipmbd: pthread_create failed\n");
goto cleanup;
}
// Create thread to handle IPMB Responses
if (pthread_create(&tid_res_handler, NULL, ipmb_res_handler, (void*) &ipmb_bus_num) < 0) {
- syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ syslog(LOG_WARNING, "ipmbd: pthread_create failed\n");
goto cleanup;
}
// Create thread to retrieve ipmb traffic from i2c bus as slave
if (pthread_create(&tid_ipmb_rx, NULL, ipmb_rx_handler, (void*) &ipmb_bus_num) < 0) {
- syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ syslog(LOG_WARNING, "ipmbd: pthread_create failed\n");
goto cleanup;
}
// Create thread to receive ipmb library requests from apps
if (pthread_create(&tid_lib_handler, NULL, ipmb_lib_handler, (void*) &ipmb_bus_num) < 0) {
- syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ syslog(LOG_WARNING, "ipmbd: pthread_create failed\n");
goto cleanup;
}
diff --git a/common/recipes-core/ipmid/files/ipmid.c b/common/recipes-core/ipmid/files/ipmid.c
index c79d3e2..0930cc2 100644
--- a/common/recipes-core/ipmid/files/ipmid.c
+++ b/common/recipes-core/ipmid/files/ipmid.c
@@ -35,6 +35,11 @@
#include <sys/un.h>
#include <openbmc/ipmi.h>
+#define SIZE_IANA_ID 3
+#define SIZE_SYS_GUID 16
+
+extern void plat_lan_init(lan_config_t *lan);
+
// TODO: Once data storage is finalized, the following structure needs
// to be retrieved/updated from persistant backend storage
static lan_config_t g_lan_config = { 0 };
@@ -245,6 +250,27 @@ app_get_device_guid (unsigned char *response, unsigned char *res_len)
*res_len = data - &res->data[0];
}
+// Get Device System GUID (IPMI/Section 22.14)
+static void
+app_get_device_sys_guid (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ int ret;
+
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ // Get the 16 bytes of System GUID from PAL library
+ ret = pal_get_sys_guid(req->payload_id, res->data);
+ if (ret) {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ *res_len = 0x00;
+ } else {
+ res->cc = CC_SUCCESS;
+ *res_len = SIZE_SYS_GUID;
+ }
+}
+
// Get BMC Global Enables (IPMI/Section 22.2)
static void
app_get_global_enables (unsigned char *response, unsigned char *res_len)
@@ -255,7 +281,7 @@ app_get_global_enables (unsigned char *response, unsigned char *res_len)
res->cc = CC_SUCCESS;
- *data++ = 0x09; // Global Enable
+ *data++ = 0x0D; // Global Enable
*res_len = data - &res->data[0];
}
@@ -279,6 +305,7 @@ app_set_sys_info_params (unsigned char *request, unsigned char *response,
break;
case SYS_INFO_PARAM_SYSFW_VER:
memcpy(g_sys_info_params.sysfw_ver, &req->data[1], SIZE_SYSFW_VER);
+ pal_set_sysfw_ver(req->payload_id, g_sys_info_params.sysfw_ver);
break;
case SYS_INFO_PARAM_SYS_NAME:
memcpy(g_sys_info_params.sys_name, &req->data[1], SIZE_SYS_NAME);
@@ -327,6 +354,7 @@ app_get_sys_info_params (unsigned char *request, unsigned char *response,
*data++ = g_sys_info_params.set_in_prog;
break;
case SYS_INFO_PARAM_SYSFW_VER:
+ pal_get_sysfw_ver(req->payload_id, g_sys_info_params.sysfw_ver);
memcpy(data, g_sys_info_params.sysfw_ver, SIZE_SYSFW_VER);
data += SIZE_SYSFW_VER;
break;
@@ -385,12 +413,11 @@ ipmi_handle_app (unsigned char *request, unsigned char req_len,
app_get_selftest_results (response, res_len);
break;
case CMD_APP_GET_DEVICE_GUID:
- case CMD_APP_GET_SYSTEM_GUID:
- // Get Device GUID and Get System GUID returns same data
- // from IPMI stack. FYI, Get System GUID will have to be
- // sent with in an IPMI session that includes session info
app_get_device_guid (response, res_len);
break;
+ case CMD_APP_GET_SYSTEM_GUID:
+ app_get_device_sys_guid (request, response, res_len);
+ break;
case CMD_APP_GET_GLOBAL_ENABLES:
app_get_global_enables (response, res_len);
break;
@@ -558,8 +585,10 @@ storage_get_sdr (unsigned char *request, unsigned char *response,
}
static void
-storage_get_sel_info (unsigned char *response, unsigned char *res_len)
+storage_get_sel_info (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
ipmi_res_t *res = (ipmi_res_t *) response;
unsigned char *data = &res->data[0];
int num_entries; // number of log entries
@@ -568,10 +597,10 @@ storage_get_sel_info (unsigned char *response, unsigned char *res_len)
time_stamp_t ts_recent_erase; // Recent Erasure Timestamp
// Use platform APIs to get SEL information
- num_entries = sel_num_entries ();
- free_space = sel_free_space ();
- sel_ts_recent_add (&ts_recent_add);
- sel_ts_recent_erase (&ts_recent_erase);
+ num_entries = sel_num_entries (req->payload_id);
+ free_space = sel_free_space (req->payload_id);
+ sel_ts_recent_add (req->payload_id, &ts_recent_add);
+ sel_ts_recent_erase (req->payload_id, &ts_recent_erase);
res->cc = CC_SUCCESS;
@@ -595,14 +624,16 @@ storage_get_sel_info (unsigned char *response, unsigned char *res_len)
}
static void
-storage_rsv_sel (unsigned char *response, unsigned char *res_len)
+storage_rsv_sel (unsigned char * request, unsigned char *response,
+ unsigned char *res_len)
{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
ipmi_res_t *res = (ipmi_res_t *) response;
unsigned char *data = &res->data[0];
int rsv_id; // SEL reservation ID
// Use platform APIs to get a SEL reservation ID
- rsv_id = sel_rsv_id ();
+ rsv_id = sel_rsv_id (req->payload_id);
if (rsv_id < 0)
{
res->cc = CC_SEL_ERASE_PROG;
@@ -634,7 +665,7 @@ storage_get_sel (unsigned char *request, unsigned char *response,
read_rec_id = (req->data[3] >> 8) | req->data[2];
// Use platform API to read the record Id and get next ID
- ret = sel_get_entry (read_rec_id, &entry, &next_rec_id);
+ ret = sel_get_entry (req->payload_id, read_rec_id, &entry, &next_rec_id);
if (ret)
{
res->cc = CC_UNSPECIFIED_ERROR;
@@ -670,7 +701,7 @@ storage_add_sel (unsigned char *request, unsigned char *response,
memcpy(entry.msg, req->data, SIZE_SEL_REC);
// Use platform APIs to add the new SEL entry
- ret = sel_add_entry (&entry, &record_id);
+ ret = sel_add_entry (req->payload_id, &entry, &record_id);
if (ret)
{
res->cc = CC_UNSPECIFIED_ERROR;
@@ -711,11 +742,11 @@ storage_clr_sel (unsigned char *request, unsigned char *response,
// Use platform APIs to clear or get status
if (req->data[5] == IPMI_SEL_INIT_ERASE)
{
- ret = sel_erase (rsv_id);
+ ret = sel_erase (req->payload_id, rsv_id);
}
else if (req->data[5] == IPMI_SEL_ERASE_STAT)
{
- ret = sel_erase_status (rsv_id, &status);
+ ret = sel_erase_status (req->payload_id, rsv_id, &status);
}
else
{
@@ -739,6 +770,37 @@ storage_clr_sel (unsigned char *request, unsigned char *response,
}
static void
+storage_get_sel_time (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ res->cc = CC_SUCCESS;
+
+ time_stamp_fill(res->data);
+
+ *res_len = SIZE_TIME_STAMP;
+
+ return;
+}
+
+static void
+storage_get_sel_utc (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ res->cc = CC_SUCCESS;
+
+ // TODO: For now, the SEL time stamp is based on UTC time,
+ // so return 0x0000 as offset. Might need to change once
+ // supporting zones in SEL time stamps
+ *data++ = 0x00;
+ *data++ = 0x00;
+
+ *res_len = data - &res->data[0];
+}
+
+static void
ipmi_handle_storage (unsigned char *request, unsigned char req_len,
unsigned char *response, unsigned char *res_len)
{
@@ -759,10 +821,10 @@ ipmi_handle_storage (unsigned char *request, unsigned char req_len,
storage_get_fruid_data (request, response, res_len);
break;
case CMD_STORAGE_GET_SEL_INFO:
- storage_get_sel_info (response, res_len);
+ storage_get_sel_info (request, response, res_len);
break;
case CMD_STORAGE_RSV_SEL:
- storage_rsv_sel (response, res_len);
+ storage_rsv_sel (request, response, res_len);
break;
case CMD_STORAGE_ADD_SEL:
storage_add_sel (request, response, res_len);
@@ -773,6 +835,12 @@ ipmi_handle_storage (unsigned char *request, unsigned char req_len,
case CMD_STORAGE_CLR_SEL:
storage_clr_sel (request, response, res_len);
break;
+ case CMD_STORAGE_GET_SEL_TIME:
+ storage_get_sel_time (response, res_len);
+ break;
+ case CMD_STORAGE_GET_SEL_UTC:
+ storage_get_sel_utc (response, res_len);
+ break;
case CMD_STORAGE_GET_SDR_INFO:
storage_get_sdr_info (response, res_len);
break;
@@ -871,6 +939,9 @@ transport_set_lan_config (unsigned char *request, unsigned char *response,
case LAN_PARAM_DEST_ADDR:
memcpy(g_lan_config.dest_addr, &req->data[2], SIZE_DEST_ADDR);
break;
+ case LAN_PARAM_IP6_ADDR:
+ memcpy(g_lan_config.ip6_addr, &req->data[2], SIZE_IP6_ADDR);
+ break;
default:
res->cc = CC_INVALID_PARAM;
break;
@@ -905,6 +976,7 @@ transport_get_lan_config (unsigned char *request, unsigned char *response,
data += SIZE_AUTH_ENABLES;
break;
case LAN_PARAM_IP_ADDR:
+ plat_lan_init(&g_lan_config);
memcpy(data, g_lan_config.ip_addr, SIZE_IP_ADDR);
data += SIZE_IP_ADDR;
break;
@@ -968,6 +1040,11 @@ transport_get_lan_config (unsigned char *request, unsigned char *response,
memcpy(data, g_lan_config.dest_addr, SIZE_DEST_ADDR);
data += SIZE_DEST_ADDR;
break;
+ case LAN_PARAM_IP6_ADDR:
+ plat_lan_init(&g_lan_config);
+ memcpy(data, g_lan_config.ip6_addr, SIZE_IP6_ADDR);
+ data += SIZE_IP6_ADDR;
+ break;
default:
res->cc = CC_INVALID_PARAM;
break;
@@ -1070,6 +1147,42 @@ oem_set_post_end (unsigned char *request, unsigned char *response,
}
static void
+oem_get_slot_info(unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ int ret;
+ uint8_t pres = 0x00;
+ uint8_t sinfo = 0x00;
+
+ // Slot info:
+ // Bit[7]: Not Present/Present (from pal)
+ // Bit[6]: Platform type (TODO from pal)
+ // Bit[5-0] : Slot# (payload_id indicates)
+ ret = pal_is_server_prsnt(req->payload_id, &pres);
+ if (ret) {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ *res_len = 0x00;
+ return;
+ }
+
+ // Populate the presence bit[7]
+ if (pres) {
+ sinfo = 0x80;
+ }
+
+ // Populate the slot number
+ sinfo |= req->payload_id;
+
+ // Prepare response buffer
+ res->cc = CC_SUCCESS;
+ res->data[0] = sinfo;
+ *res_len = 0x01;
+}
+
+static void
ipmi_handle_oem (unsigned char *request, unsigned char req_len,
unsigned char *response, unsigned char *res_len)
{
@@ -1093,6 +1206,9 @@ ipmi_handle_oem (unsigned char *request, unsigned char req_len,
case CMD_OEM_SET_POST_END:
oem_set_post_end (request, response, res_len);
break;
+ case CMD_OEM_GET_SLOT_INFO:
+ oem_get_slot_info (request, response, res_len);
+ break;
default:
res->cc = CC_INVALID_CMD;
break;
@@ -1114,21 +1230,22 @@ oem_1s_handle_ipmb_kcs(unsigned char *request, unsigned char req_len,
// Add the payload id from the bridged command
req_buf[0] = req->payload_id;
- // Remove OEM IPMI Header + 1 byte for BIC interface
+ // Remove OEM IPMI Header (including 1 byte for interface type, 3 bytes for IANA ID)
// The offset moves by one due to the payload ID
- memcpy(&req_buf[1], &request[BIC_INTF_HDR_SIZE + 1], req_len - BIC_INTF_HDR_SIZE);
+ memcpy(&req_buf[1], &request[BIC_INTF_HDR_SIZE], req_len - BIC_INTF_HDR_SIZE + 1);
// Send the bridged KCS command along with the payload ID
// The offset moves by one due to the payload ID
ipmi_handle(req_buf, req_len - BIC_INTF_HDR_SIZE + 1, res_buf, res_len);
- // Copy the response back
- memcpy(&res->data[1], res_buf, *res_len);
+ // Copy the response back (1 byte interface type, 3 bytes for IANA ID)
+ memcpy(&res->data[4], res_buf, *res_len);
// Add the OEM command's response
res->cc = CC_SUCCESS;
- res->data[0] = req->data[0]; // Bridge-IC interface
- *res_len += 1;
+ memcpy(res->data, &req->data, SIZE_IANA_ID); // IANA ID
+ res->data[3] = req->data[3]; // Bridge-IC interface
+ *res_len += 4; // Interface type + IANA ID
}
static void
@@ -1139,32 +1256,38 @@ oem_1s_handle_ipmb_req(unsigned char *request, unsigned char req_len,
ipmi_res_t *res = (ipmi_res_t *) response;
// handle based on Bridge-IC interface
- switch(req->data[0]) {
+ switch(req->data[3]) {
case BIC_INTF_ME:
// TODO: Need to call ME command handler
+#ifdef DEBUG
syslog(LOG_INFO, "oem_1s_handle_ipmb_req: Command received from ME for "
"payload#%d\n", req->payload_id);
- res->data[0] = BIC_INTF_ME;
+#endif
+ memcpy(res->data, req->data, 4); //IANA ID + Interface type
res->cc = CC_SUCCESS;
- *res_len = 1;
+ *res_len = 4;
break;
case BIC_INTF_SOL:
// TODO: Need to call Optional SoL message handler
+#ifdef DEBUG
syslog(LOG_INFO, "oem_1s_handle_ipmb_req: Command received from SOL for "
"payload#%d\n", req->payload_id);
- res->data[0] = BIC_INTF_SOL;
+#endif
+ memcpy(res->data, req->data, 4); //IANA ID + Interface type
res->cc = CC_SUCCESS;
- *res_len = 1;
+ *res_len = 4;
break;
case BIC_INTF_KCS:
+ case BIC_INTF_KCS_SMM:
oem_1s_handle_ipmb_kcs(request, req_len, response, res_len);
break;
default:
// TODO: Need to add additonal interface handler, if supported
- syslog(LOG_ALERT, "oem_1s_handle_ipmb_req: Command received on intf#%d "
- "for payload#%d", req->data[0], req->payload_id);
+ syslog(LOG_WARNING, "oem_1s_handle_ipmb_req: Command received on intf#%d "
+ "for payload#%d", req->data[3], req->payload_id);
+ memcpy(res->data, req->data, 4); //IANA ID + Interface type
res->cc = CC_INVALID_PARAM;
- *res_len = 0;
+ *res_len = 4;
break;
}
}
@@ -1187,62 +1310,70 @@ ipmi_handle_oem_1s(unsigned char *request, unsigned char req_len,
break;
case CMD_OEM_1S_INTR:
syslog(LOG_INFO, "ipmi_handle_oem_1s: 1S server interrupt#%d received "
- "for payload#%d\n", req->data[0], req->payload_id);
+ "for payload#%d\n", req->data[3], req->payload_id);
res->cc = CC_SUCCESS;
- *res_len = 0;
+ memcpy(res->data, req->data, SIZE_IANA_ID); //IANA ID
+ *res_len = 3;
break;
case CMD_OEM_1S_POST_BUF:
- for (i = 1; i <= req->data[0]; i++) {
+ // Skip the first 3 bytes of IANA ID and one byte of length field
+ for (i = SIZE_IANA_ID+1; i <= req->data[3]; i++) {
pal_post_handle(req->payload_id, req->data[i]);
}
res->cc = CC_SUCCESS;
- *res_len = 0;
+ memcpy(res->data, req->data, SIZE_IANA_ID); //IANA ID
+ *res_len = 3;
break;
case CMD_OEM_1S_PLAT_DISC:
syslog(LOG_INFO, "ipmi_handle_oem_1s: Platform Discovery received for "
"payload#%d\n", req->payload_id);
res->cc = CC_SUCCESS;
- *res_len = 0;
+ memcpy(res->data, req->data, SIZE_IANA_ID); //IANA ID
+ *res_len = 3;
break;
case CMD_OEM_1S_BIC_RESET:
syslog(LOG_INFO, "ipmi_handle_oem_1s: BIC Reset received "
"for payload#%d\n", req->payload_id);
- if (req->data[0] == 0x0) {
- syslog(LOG_ALERT, "Cold Reset by Firmware Update\n");
+ if (req->data[3] == 0x0) {
+ syslog(LOG_WARNING, "Cold Reset by Firmware Update\n");
res->cc = CC_SUCCESS;
- } else if (req->data[1] == 0x01) {
- syslog(LOG_ALERT, "WDT Reset\n");
+ } else if (req->data[3] == 0x01) {
+ syslog(LOG_WARNING, "WDT Reset\n");
res->cc = CC_SUCCESS;
} else {
- syslog(LOG_ALERT, "Error\n");
+ syslog(LOG_WARNING, "Error\n");
res->cc = CC_INVALID_PARAM;
}
- *res_len = 0;
+ memcpy(res->data, req->data, SIZE_IANA_ID); //IANA ID
+ *res_len = 3;
break;
case CMD_OEM_1S_BIC_UPDATE_MODE:
+#ifdef DEBUG
syslog(LOG_INFO, "ipmi_handle_oem_1s: BIC Update Mode received "
"for payload#%d\n", req->payload_id);
-
- if (req->data[0] == 0x0) {
+#endif
+ if (req->data[3] == 0x0) {
syslog(LOG_INFO, "Normal Mode\n");
res->cc = CC_SUCCESS;
- } else if (req->data[1] == 0x0F) {
+ } else if (req->data[3] == 0x0F) {
syslog(LOG_INFO, "Update Mode\n");
res->cc = CC_SUCCESS;
} else {
- syslog(LOG_ALERT, "Error\n");
+ syslog(LOG_WARNING, "Error\n");
res->cc = CC_INVALID_PARAM;
}
- *res_len = 0;
+ memcpy(res->data, req->data, SIZE_IANA_ID); //IANA ID
+ *res_len = 3;
break;
default:
res->cc = CC_INVALID_CMD;
- *res_len = 0;
+ memcpy(res->data, req->data, SIZE_IANA_ID); //IANA ID
+ *res_len = 3;
break;
}
pthread_mutex_unlock(&m_oem_1s);
@@ -1306,26 +1437,37 @@ ipmi_handle (unsigned char *request, unsigned char req_len,
void
*conn_handler(void *socket_desc) {
- int sock = *(int*)socket_desc;
+ int *p_sock = (int*)socket_desc;
+ int sock = *p_sock;
int n;
unsigned char req_buf[MAX_IPMI_MSG_SIZE];
unsigned char res_buf[MAX_IPMI_MSG_SIZE];
unsigned char res_len = 0;
+ struct timeval tv;
+ int rc = 0;
+
+ // setup timeout for receving on socket
+ tv.tv_sec = TIMEOUT_IPMI;
+ tv.tv_usec = 0;
+
+ setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
n = recv (sock, req_buf, sizeof(req_buf), 0);
+ rc = errno;
if (n <= 0) {
- syslog(LOG_ALERT, "ipmid: recv() failed with %d\n", n);
+ syslog(LOG_WARNING, "ipmid: recv() failed with %d, errno: %d\n", n, rc);
goto conn_cleanup;
}
ipmi_handle(req_buf, n, res_buf, &res_len);
if (send (sock, res_buf, res_len, 0) < 0) {
- syslog(LOG_ALERT, "ipmid: send() failed\n");
+ syslog(LOG_WARNING, "ipmid: send() failed\n");
}
conn_cleanup:
close(sock);
+ free(p_sock);
pthread_exit(NULL);
return 0;
@@ -1338,13 +1480,16 @@ main (void)
int s, s2, t, len;
struct sockaddr_un local, remote;
pthread_t tid;
+ int *p_s2;
+ int rc = 0;
- daemon(1, 0);
+ daemon(1, 1);
openlog("ipmid", LOG_CONS, LOG_DAEMON);
plat_fruid_init();
plat_sensor_init();
+ plat_lan_init(&g_lan_config);
sdr_init();
sel_init();
@@ -1358,7 +1503,7 @@ main (void)
if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
{
- syslog(LOG_ALERT, "ipmid: socket() failed\n");
+ syslog(LOG_WARNING, "ipmid: socket() failed\n");
exit (1);
}
@@ -1368,30 +1513,35 @@ main (void)
len = strlen (local.sun_path) + sizeof (local.sun_family);
if (bind (s, (struct sockaddr *) &local, len) == -1)
{
- syslog(LOG_ALERT, "ipmid: bind() failed\n");
+ syslog(LOG_WARNING, "ipmid: bind() failed\n");
exit (1);
}
if (listen (s, 5) == -1)
{
- syslog(LOG_ALERT, "ipmid: listen() failed\n");
+ syslog(LOG_WARNING, "ipmid: listen() failed\n");
exit (1);
}
while(1) {
int n;
t = sizeof (remote);
+ // TODO: seen accept() call fails and need further debug
if ((s2 = accept (s, (struct sockaddr *) &remote, &t)) < 0) {
- syslog(LOG_ALERT, "ipmid: accept() failed\n");
- break;
+ rc = errno;
+ syslog(LOG_WARNING, "ipmid: accept() failed with ret: %x, errno: %x\n", s2, rc);
+ sleep(5);
+ continue;
}
// Creating a worker thread to handle the request
// TODO: Need to monitor the server performance with higher load and
// see if we need to create pre-defined number of workers and schedule
// the requests among them.
- if (pthread_create(&tid, NULL, conn_handler, (void*) &s2) < 0) {
- syslog(LOG_ALERT, "ipmid: pthread_create failed\n");
+ p_s2 = malloc(sizeof(int));
+ *p_s2 = s2;
+ if (pthread_create(&tid, NULL, conn_handler, (void*) p_s2) < 0) {
+ syslog(LOG_WARNING, "ipmid: pthread_create failed\n");
close(s2);
continue;
}
diff --git a/common/recipes-core/ipmid/files/sdr.c b/common/recipes-core/ipmid/files/sdr.c
index 91a4df5..78d74c3 100644
--- a/common/recipes-core/ipmid/files/sdr.c
+++ b/common/recipes-core/ipmid/files/sdr.c
@@ -88,7 +88,7 @@ static int
sdr_add_entry(sdr_rec_t *rec, int *rec_id) {
// If SDR is full, return error
if (sdr_num_entries() == SDR_RECORDS_MAX) {
- syslog(LOG_ALERT, "sdr_add_entry: SDR full\n");
+ syslog(LOG_WARNING, "sdr_add_entry: SDR full\n");
return -1;
}
@@ -137,7 +137,7 @@ sdr_add_mgmt_rec(sensor_mgmt_t *p_rec) {
// Add this record to SDR repo
if (sdr_add_entry(&sdr, &rec_id)) {
- syslog(LOG_ALERT, "sdr_add_mgmt_rec: sdr_add_entry failed\n");
+ syslog(LOG_WARNING, "sdr_add_mgmt_rec: sdr_add_entry failed\n");
return -1;
}
@@ -176,7 +176,7 @@ sdr_add_disc_rec(sensor_disc_t *p_rec) {
// Add this record to SDR repo
if (sdr_add_entry(&sdr, &rec_id)) {
- syslog(LOG_ALERT, "sdr_add_disc_rec: sdr_add_entry failed\n");
+ syslog(LOG_WARNING, "sdr_add_disc_rec: sdr_add_entry failed\n");
return -1;
}
@@ -237,7 +237,7 @@ sdr_add_thresh_rec(sensor_thresh_t *p_rec) {
// Add this record to SDR repo
if (sdr_add_entry(&sdr, &rec_id)) {
- syslog(LOG_ALERT, "sdr_add_thresh_rec: sdr_add_entry failed\n");
+ syslog(LOG_WARNING, "sdr_add_thresh_rec: sdr_add_entry failed\n");
return -1;
}
@@ -263,7 +263,7 @@ sdr_add_oem_rec(sensor_oem_t *p_rec) {
// Add this record to SDR repo
if (sdr_add_entry(&sdr, &rec_id)) {
- syslog(LOG_ALERT, "sdr_add_oem_rec: sdr_add_entry failed\n");
+ syslog(LOG_WARNING, "sdr_add_oem_rec: sdr_add_entry failed\n");
return -1;
}
@@ -323,7 +323,7 @@ sdr_get_entry(int rsv_id, int read_rec_id, sdr_rec_t *rec,
// Make sure the rsv_id matches
if (rsv_id != g_rsv_id) {
- syslog(LOG_ALERT, "sdr_get_entry: Reservation ID mismatch\n");
+ syslog(LOG_WARNING, "sdr_get_entry: Reservation ID mismatch\n");
return -1;
}
@@ -338,19 +338,19 @@ sdr_get_entry(int rsv_id, int read_rec_id, sdr_rec_t *rec,
// If the SDR repo is empty return error
if (sdr_num_entries() == 0) {
- syslog(LOG_ALERT, "sdr_get_entry: No entries\n");
+ syslog(LOG_WARNING, "sdr_get_entry: No entries\n");
return -1;
}
// Check for boundary conditions
if ((index < SDR_INDEX_MIN) || (index > SDR_INDEX_MAX)) {
- syslog(LOG_ALERT, "sdr_get_entry: Invalid Record ID %d\n", read_rec_id);
+ syslog(LOG_WARNING, "sdr_get_entry: Invalid Record ID %d\n", read_rec_id);
return -1;
}
// Check to make sure the given id is valid
if (index < g_sdr_hdr.begin || index >= g_sdr_hdr.end) {
- syslog(LOG_ALERT, "sdr_get_entry: Wrong Record ID %d\n", read_rec_id);
+ syslog(LOG_WARNING, "sdr_get_entry: Wrong Record ID %d\n", read_rec_id);
return -1;
}
diff --git a/common/recipes-core/ipmid/files/sel.c b/common/recipes-core/ipmid/files/sel.c
index d598bb1..1b45b42 100644
--- a/common/recipes-core/ipmid/files/sel.c
+++ b/common/recipes-core/ipmid/files/sel.c
@@ -31,9 +31,19 @@
#include <errno.h>
#include <syslog.h>
#include <string.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+
+#if defined(CONFIG_YOSEMITE)
+#define MAX_NODES 4
+#else
+#define MAX_NODES 1
+#endif
// SEL File.
-#define SEL_LOG_FILE "/mnt/data/sel.bin"
+#define SEL_LOG_FILE "/mnt/data/sel%d.bin"
+#define SIZE_PATH_MAX 32
// SEL Header magic number
#define SEL_HDR_MAGIC 0xFBFBFBFB
@@ -75,24 +85,27 @@ typedef struct {
} sel_hdr_t;
// Keep track of last Reservation ID
-static int g_rsv_id = 0x01;
+static int g_rsv_id[MAX_NODES+1];
// Cached version of SEL Header and data
-static sel_hdr_t g_sel_hdr;
-static sel_msg_t g_sel_data[SEL_ELEMS_MAX];
+static sel_hdr_t g_sel_hdr[MAX_NODES+1];
+static sel_msg_t g_sel_data[MAX_NODES+1][SEL_ELEMS_MAX];
// Local helper functions to interact with file system
static int
-file_get_sel_hdr(void) {
+file_get_sel_hdr(int node) {
FILE *fp;
+ char fpath[SIZE_PATH_MAX] = {0};
+
+ sprintf(fpath, SEL_LOG_FILE, node);
- fp = fopen(SEL_LOG_FILE, "r");
+ fp = fopen(fpath, "r");
if (fp == NULL) {
return -1;
}
- if (fread(&g_sel_hdr, sizeof(sel_hdr_t), 1, fp) <= 0) {
- syslog(LOG_ALERT, "file_get_sel_hdr: fread\n");
+ if (fread(&g_sel_hdr[node], sizeof(sel_hdr_t), 1, fp) <= 0) {
+ syslog(LOG_WARNING, "file_get_sel_hdr: fread\n");
fclose (fp);
return -1;
}
@@ -102,25 +115,28 @@ file_get_sel_hdr(void) {
}
static int
-file_get_sel_data(void) {
+file_get_sel_data(int node) {
FILE *fp;
int i, j;
+ char fpath[SIZE_PATH_MAX] = {0};
- fp = fopen(SEL_LOG_FILE, "r");
+ sprintf(fpath, SEL_LOG_FILE, node);
+
+ fp = fopen(fpath, "r");
if (fp == NULL) {
- syslog(LOG_ALERT, "file_get_sel_data: fopen\n");
+ syslog(LOG_WARNING, "file_get_sel_data: fopen\n");
return -1;
}
if (fseek(fp, SEL_DATA_OFFSET, SEEK_SET)) {
- syslog(LOG_ALERT, "file_get_sel_data: fseek\n");
+ syslog(LOG_WARNING, "file_get_sel_data: fseek\n");
fclose(fp);
return -1;
}
unsigned char buf[SEL_ELEMS_MAX * 16];
if (fread(buf, 1, SEL_ELEMS_MAX * sizeof(sel_msg_t), fp) <= 0) {
- syslog(LOG_ALERT, "file_get_sel_data: fread\n");
+ syslog(LOG_WARNING, "file_get_sel_data: fread\n");
fclose(fp);
return -1;
}
@@ -129,7 +145,7 @@ file_get_sel_data(void) {
for (i = 0; i < SEL_ELEMS_MAX; i++) {
for (j = 0; j < sizeof(sel_msg_t);j++) {
- g_sel_data[i].msg[j] = buf[i*16 + j];
+ g_sel_data[node][i].msg[j] = buf[i*16 + j];
}
}
@@ -137,17 +153,20 @@ file_get_sel_data(void) {
}
static int
-file_store_sel_hdr(void) {
+file_store_sel_hdr(int node) {
FILE *fp;
+ char fpath[SIZE_PATH_MAX] = {0};
+
+ sprintf(fpath, SEL_LOG_FILE, node);
- fp = fopen(SEL_LOG_FILE, "r+");
+ fp = fopen(fpath, "r+");
if (fp == NULL) {
- syslog(LOG_ALERT, "file_store_sel_hdr: fopen\n");
+ syslog(LOG_WARNING, "file_store_sel_hdr: fopen\n");
return -1;
}
- if (fwrite(&g_sel_hdr, sizeof(sel_hdr_t), 1, fp) <= 0) {
- syslog(LOG_ALERT, "file_store_sel_hdr: fwrite\n");
+ if (fwrite(&g_sel_hdr[node], sizeof(sel_hdr_t), 1, fp) <= 0) {
+ syslog(LOG_WARNING, "file_store_sel_hdr: fwrite\n");
fclose(fp);
return -1;
}
@@ -158,13 +177,16 @@ file_store_sel_hdr(void) {
}
static int
-file_store_sel_data(int recId, sel_msg_t *data) {
+file_store_sel_data(int node, int recId, sel_msg_t *data) {
FILE *fp;
int index;
+ char fpath[SIZE_PATH_MAX] = {0};
- fp = fopen(SEL_LOG_FILE, "r+");
+ sprintf(fpath, SEL_LOG_FILE, node);
+
+ fp = fopen(fpath, "r+");
if (fp == NULL) {
- syslog(LOG_ALERT, "file_store_sel_data: fopen\n");
+ syslog(LOG_WARNING, "file_store_sel_data: fopen\n");
return -1;
}
@@ -172,13 +194,13 @@ file_store_sel_data(int recId, sel_msg_t *data) {
index = (recId-1) * sizeof(sel_msg_t);
if (fseek(fp, SEL_DATA_OFFSET+index, SEEK_SET)) {
- syslog(LOG_ALERT, "file_store_sel_data: fseek\n");
+ syslog(LOG_WARNING, "file_store_sel_data: fseek\n");
fclose(fp);
return -1;
}
if (fwrite(data->msg, sizeof(sel_msg_t), 1, fp) <= 0) {
- syslog(LOG_ALERT, "file_store_sel_data: fwrite\n");
+ syslog(LOG_WARNING, "file_store_sel_data: fwrite\n");
fclose(fp);
return -1;
}
@@ -188,37 +210,103 @@ file_store_sel_data(int recId, sel_msg_t *data) {
return 0;
}
+static void
+dump_sel_syslog(int fru, sel_msg_t *data) {
+ int i = 0;
+ char temp_str[8] = {0};
+ char str[128] = {0};
+
+ for (i = 0; i < 15; i++) {
+ sprintf(temp_str, "%02X:", data->msg[i]);
+ strcat(str, temp_str);
+ }
+ sprintf(temp_str, "%02X", data->msg[15]);
+ strcat(str, temp_str);
+
+ syslog(LOG_CRIT, "SEL Entry, FRU: %d, Content: %s\n", fru, str);
+}
+
+static void
+parse_sel(uint8_t fru, sel_msg_t *data) {
+ int i = 0;
+ uint32_t timestamp;
+ char *sel = data->msg;
+ uint8_t sensor_type;
+ uint8_t sensor_num;
+ uint8_t event_dir;
+ uint8_t type_num;
+ uint8_t event_data[3];
+ char sensor_name[32];
+ char error_log[64];
+ char error_type[64];
+ char status[16];
+ int ret;
+
+ //memcpy(timestamp, (uint8_t *) &sel[3], 4);
+ timestamp = 0;
+ timestamp |= sel[3];
+ timestamp |= sel[4] << 8;
+ timestamp |= sel[5] << 16;
+ timestamp |= sel[6] << 24;
+
+ sensor_type = (uint8_t) sel[10];
+ sensor_num = (uint8_t) sel[11];
+ event_dir = ((uint8_t) sel[12] & (1 << 7)) >> 7; /* Bit 7 of sel[12] */
+ type_num = (uint8_t) sel[12]; /* Bits 6:0 */
+ memcpy(event_data, (uint8_t *) &sel[13], 3);
+
+ sprintf(status, event_dir ? "DEASSERT" : "ASSERT");
+
+ if (type_num == 0x1) {
+ sprintf(error_type, "Threshold");
+ } else if (type_num >= 0x2 || type_num <= 0xC || type_num == 0x6F) {
+ sprintf(error_type, "Discrete");
+ } else if (type_num >= 0x70 || type_num <= 0x7F) {
+ sprintf(error_type, "OEM");
+ } else {
+ sprintf(error_type, "Unknown");
+ }
+
+ ret = pal_get_event_sensor_name(fru, sensor_num, sensor_name);
+ ret = pal_parse_sel(fru, sensor_num, event_data, error_log);
+ ret = pal_sel_handler(fru, sensor_num);
+
+ syslog(LOG_CRIT, "SEL Entry, %s: FRU: %d, Sensor: 0x%X, Name: %s,"
+ " Timestamp: %u, Event Type: %s, Event Data: %s",
+ status, fru, sensor_num, sensor_name, timestamp, error_type, error_log);
+}
+
// Platform specific SEL API entry points
// Retrieve time stamp for recent add operation
void
-sel_ts_recent_add(time_stamp_t *ts) {
- memcpy(ts->ts, g_sel_hdr.ts_add.ts, 0x04);
+sel_ts_recent_add(int node, time_stamp_t *ts) {
+ memcpy(ts->ts, g_sel_hdr[node].ts_add.ts, 0x04);
}
// Retrieve time stamp for recent erase operation
void
-sel_ts_recent_erase(time_stamp_t *ts) {
- memcpy(ts->ts, g_sel_hdr.ts_erase.ts, 0x04);
+sel_ts_recent_erase(int node, time_stamp_t *ts) {
+ memcpy(ts->ts, g_sel_hdr[node].ts_erase.ts, 0x04);
}
// Retrieve total number of entries in SEL log
int
-sel_num_entries(void) {
- if (g_sel_hdr.begin <= g_sel_hdr.end) {
- return (g_sel_hdr.end - g_sel_hdr.begin);
+sel_num_entries(int node) {
+ if (g_sel_hdr[node].begin <= g_sel_hdr[node].end) {
+ return (g_sel_hdr[node].end - g_sel_hdr[node].begin);
} else {
- return (g_sel_hdr.end + (SEL_INDEX_MAX - g_sel_hdr.begin + 1));
+ return (g_sel_hdr[node].end + (SEL_INDEX_MAX - g_sel_hdr[node].begin + 1));
}
}
// Retrieve total free space available in SEL log
int
-sel_free_space(void) {
+sel_free_space(int node) {
int total_space;
int used_space;
total_space = SEL_RECORDS_MAX * sizeof(sel_msg_t);
- used_space = sel_num_entries() * sizeof(sel_msg_t);
+ used_space = sel_num_entries(node) * sizeof(sel_msg_t);
return (total_space - used_space);
}
@@ -226,28 +314,28 @@ sel_free_space(void) {
// Reserve an ID that will be used in later operations
// IPMI/Section 31.4
int
-sel_rsv_id() {
+sel_rsv_id(int node) {
// Increment the current reservation ID and return
- if (g_rsv_id++ == SEL_RSVID_MAX) {
- g_rsv_id = SEL_RSVID_MIN;
+ if (g_rsv_id[node]++ == SEL_RSVID_MAX) {
+ g_rsv_id[node] = SEL_RSVID_MIN;
}
- return g_rsv_id;
+ return g_rsv_id[node];
}
// Get the SEL entry for a given record ID
// IPMI/Section 31.5
int
-sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id) {
+sel_get_entry(int node, int read_rec_id, sel_msg_t *msg, int *next_rec_id) {
int index;
// Find the index in to array based on given index
if (read_rec_id == SEL_RECID_FIRST) {
- index = g_sel_hdr.begin;
+ index = g_sel_hdr[node].begin;
} else if (read_rec_id == SEL_RECID_LAST) {
- if (g_sel_hdr.end) {
- index = g_sel_hdr.end - 1;
+ if (g_sel_hdr[node].end) {
+ index = g_sel_hdr[node].end - 1;
} else {
index = SEL_INDEX_MAX;
}
@@ -256,34 +344,34 @@ sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id) {
}
// If the log is empty return error
- if (sel_num_entries() == 0) {
- syslog(LOG_ALERT, "sel_get_entry: No entries\n");
+ if (sel_num_entries(node) == 0) {
+ syslog(LOG_WARNING, "sel_get_entry: No entries\n");
return -1;
}
// Check for boundary conditions
if ((index < SEL_INDEX_MIN) || (index > SEL_INDEX_MAX)) {
- syslog(LOG_ALERT, "sel_get_entry: Invalid Record ID %d\n", read_rec_id);
+ syslog(LOG_WARNING, "sel_get_entry: Invalid Record ID %d\n", read_rec_id);
return -1;
}
// If begin < end, check to make sure the given id falls between
- if (g_sel_hdr.begin < g_sel_hdr.end) {
- if (index < g_sel_hdr.begin || index >= g_sel_hdr.end) {
- syslog(LOG_ALERT, "sel_get_entry: Wrong Record ID %d\n", read_rec_id);
+ if (g_sel_hdr[node].begin < g_sel_hdr[node].end) {
+ if (index < g_sel_hdr[node].begin || index >= g_sel_hdr[node].end) {
+ syslog(LOG_WARNING, "sel_get_entry: Wrong Record ID %d\n", read_rec_id);
return -1;
}
}
// If end < begin, check to make sure the given id is valid
- if (g_sel_hdr.begin > g_sel_hdr.end) {
- if (index >= g_sel_hdr.end && index < g_sel_hdr.begin) {
- syslog(LOG_ALERT, "sel_get_entry: Wrong Record ID2 %d\n", read_rec_id);
+ if (g_sel_hdr[node].begin > g_sel_hdr[node].end) {
+ if (index >= g_sel_hdr[node].end && index < g_sel_hdr[node].begin) {
+ syslog(LOG_WARNING, "sel_get_entry: Wrong Record ID2 %d\n", read_rec_id);
return -1;
}
}
- memcpy(msg->msg, g_sel_data[index].msg, sizeof(sel_msg_t));
+ memcpy(msg->msg, g_sel_data[node][index].msg, sizeof(sel_msg_t));
// Return the next record ID in the log
*next_rec_id = read_rec_id++;
@@ -292,7 +380,7 @@ sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id) {
}
// If this is the last entry in the log, return 0xFFFF
- if (*next_rec_id == g_sel_hdr.end) {
+ if (*next_rec_id == g_sel_hdr[node].end) {
*next_rec_id = SEL_RECID_LAST;
}
@@ -302,13 +390,13 @@ sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id) {
// Add a new entry in to SEL log
// IPMI/Section 31.6
int
-sel_add_entry(sel_msg_t *msg, int *rec_id) {
+sel_add_entry(int node, sel_msg_t *msg, int *rec_id) {
// If the SEL if full, roll over. To keep track of empty condition, use
// one empty location less than the max records.
- if (sel_num_entries() == SEL_RECORDS_MAX) {
- syslog(LOG_ALERT, "sel_add_entry: SEL rollover\n");
- if (++g_sel_hdr.begin > SEL_INDEX_MAX) {
- g_sel_hdr.begin = SEL_INDEX_MIN;
+ if (sel_num_entries(node) == SEL_RECORDS_MAX) {
+ syslog(LOG_WARNING, "sel_add_entry: SEL rollover\n");
+ if (++g_sel_hdr[node].begin > SEL_INDEX_MAX) {
+ g_sel_hdr[node].begin = SEL_INDEX_MIN;
}
}
@@ -316,27 +404,33 @@ sel_add_entry(sel_msg_t *msg, int *rec_id) {
time_stamp_fill(&msg->msg[3]);
// Add the enry at end
- memcpy(g_sel_data[g_sel_hdr.end].msg, msg->msg, sizeof(sel_msg_t));
+ memcpy(g_sel_data[node][g_sel_hdr[node].end].msg, msg->msg, sizeof(sel_msg_t));
// Return the newly added record ID
- *rec_id = g_sel_hdr.end+1;
+ *rec_id = g_sel_hdr[node].end+1;
- if (file_store_sel_data(*rec_id, msg)) {
- syslog(LOG_ALERT, "sel_add_entry: file_store_sel_data\n");
+ // Print the data in syslog
+ dump_sel_syslog(node, msg);
+
+ // Parse the SEL message
+ parse_sel((uint8_t) node, msg);
+
+ if (file_store_sel_data(node, *rec_id, msg)) {
+ syslog(LOG_WARNING, "sel_add_entry: file_store_sel_data\n");
return -1;
}
// Increment the end pointer
- if (++g_sel_hdr.end > SEL_INDEX_MAX) {
- g_sel_hdr.end = SEL_INDEX_MIN;
+ if (++g_sel_hdr[node].end > SEL_INDEX_MAX) {
+ g_sel_hdr[node].end = SEL_INDEX_MIN;
}
// Update timestamp for add in header
- time_stamp_fill(g_sel_hdr.ts_add.ts);
+ time_stamp_fill(g_sel_hdr[node].ts_add.ts);
// Store the structure persistently
- if (file_store_sel_hdr()) {
- syslog(LOG_ALERT, "sel_add_entry: file_store_sel_hdr\n");
+ if (file_store_sel_hdr(node)) {
+ syslog(LOG_WARNING, "sel_add_entry: file_store_sel_hdr\n");
return -1;
}
@@ -347,21 +441,21 @@ sel_add_entry(sel_msg_t *msg, int *rec_id) {
// IPMI/Section 31.9
// Note: To reduce wear/tear, instead of erasing, manipulating the metadata
int
-sel_erase(int rsv_id) {
- if (rsv_id != g_rsv_id) {
+sel_erase(int node, int rsv_id) {
+ if (rsv_id != g_rsv_id[node]) {
return -1;
}
// Erase SEL Logs
- g_sel_hdr.begin = SEL_INDEX_MIN;
- g_sel_hdr.end = SEL_INDEX_MIN;
+ g_sel_hdr[node].begin = SEL_INDEX_MIN;
+ g_sel_hdr[node].end = SEL_INDEX_MIN;
// Update timestamp for erase in header
- time_stamp_fill(g_sel_hdr.ts_erase.ts);
+ time_stamp_fill(g_sel_hdr[node].ts_erase.ts);
// Store the structure persistently
- if (file_store_sel_hdr()) {
- syslog(LOG_ALERT, "sel_erase: file_store_sel_hdr\n");
+ if (file_store_sel_hdr(node)) {
+ syslog(LOG_WARNING, "sel_erase: file_store_sel_hdr\n");
return -1;
}
@@ -372,8 +466,8 @@ sel_erase(int rsv_id) {
// IPMI/Section 31.2
// Note: Since we are not doing offline erasing, need not return in-progress state
int
-sel_erase_status(int rsv_id, sel_erase_stat_t *status) {
- if (rsv_id != g_rsv_id) {
+sel_erase_status(int node, int rsv_id, sel_erase_stat_t *status) {
+ if (rsv_id != g_rsv_id[node]) {
return -1;
}
@@ -384,21 +478,24 @@ sel_erase_status(int rsv_id, sel_erase_stat_t *status) {
}
// Initialize SEL log file
-int
-sel_init(void) {
+static int
+sel_node_init(int node) {
FILE *fp;
int i;
+ char fpath[SIZE_PATH_MAX] = {0};
+
+ sprintf(fpath, SEL_LOG_FILE, node);
// Check if the file exists or not
- if (access(SEL_LOG_FILE, F_OK) == 0) {
+ if (access(fpath, F_OK) == 0) {
// Since file is present, fetch all the contents to cache
- if (file_get_sel_hdr()) {
- syslog(LOG_ALERT, "init_sel: file_get_sel_hdr\n");
+ if (file_get_sel_hdr(node)) {
+ syslog(LOG_WARNING, "init_sel: file_get_sel_hdr\n");
return -1;
}
- if (file_get_sel_data()) {
- syslog(LOG_ALERT, "init_sel: file_get_sel_data\n");
+ if (file_get_sel_data(node)) {
+ syslog(LOG_WARNING, "init_sel: file_get_sel_data\n");
return -1;
}
@@ -406,35 +503,52 @@ sel_init(void) {
}
// File not present, so create the file
- fp = fopen(SEL_LOG_FILE, "w+");
+ fp = fopen(fpath, "w+");
if (fp == NULL) {
- syslog(LOG_ALERT, "init_sel: fopen\n");
+ syslog(LOG_WARNING, "init_sel: fopen\n");
return -1;
}
fclose (fp);
// Populate SEL Header in to the file
- g_sel_hdr.magic = SEL_HDR_MAGIC;
- g_sel_hdr.version = SEL_HDR_VERSION;
- g_sel_hdr.begin = SEL_INDEX_MIN;
- g_sel_hdr.end = SEL_INDEX_MIN;
- memset(g_sel_hdr.ts_add.ts, 0x0, 4);
- memset(g_sel_hdr.ts_erase.ts, 0x0, 4);
-
- if (file_store_sel_hdr()) {
- syslog(LOG_ALERT, "init_sel: file_store_sel_hdr\n");
+ g_sel_hdr[node].magic = SEL_HDR_MAGIC;
+ g_sel_hdr[node].version = SEL_HDR_VERSION;
+ g_sel_hdr[node].begin = SEL_INDEX_MIN;
+ g_sel_hdr[node].end = SEL_INDEX_MIN;
+ memset(g_sel_hdr[node].ts_add.ts, 0x0, 4);
+ memset(g_sel_hdr[node].ts_erase.ts, 0x0, 4);
+
+ if (file_store_sel_hdr(node)) {
+ syslog(LOG_WARNING, "init_sel: file_store_sel_hdr\n");
return -1;
}
// Populate SEL Data in to the file
for (i = 1; i <= SEL_RECORDS_MAX; i++) {
sel_msg_t msg = {0};
- if (file_store_sel_data(i, &msg)) {
- syslog(LOG_ALERT, "init_sel: file_store_sel_data\n");
+ if (file_store_sel_data(node, i, &msg)) {
+ syslog(LOG_WARNING, "init_sel: file_store_sel_data\n");
return -1;
}
}
+ g_rsv_id[node] = 0x01;
+
return 0;
}
+
+int
+sel_init(void) {
+ int ret;
+ int i;
+
+ for (i = 1; i < MAX_NODES+1; i++) {
+ ret = sel_node_init(i);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return ret;
+}
diff --git a/common/recipes-core/ipmid/files/sel.h b/common/recipes-core/ipmid/files/sel.h
index 3bb9a2f..500b078 100644
--- a/common/recipes-core/ipmid/files/sel.h
+++ b/common/recipes-core/ipmid/files/sel.h
@@ -37,15 +37,15 @@ typedef struct {
unsigned char msg[16];
} sel_msg_t;
-void sel_ts_recent_add(time_stamp_t *ts);
-void sel_ts_recent_erase(time_stamp_t *ts);
-int sel_num_entries(void);
-int sel_free_space(void);
-int sel_rsv_id();
-int sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id);
-int sel_add_entry(sel_msg_t *msg, int *rec_id);
-int sel_erase(int rsv_id);
-int sel_erase_status(int rsv_id, sel_erase_stat_t *status);
+void sel_ts_recent_add(int node, time_stamp_t *ts);
+void sel_ts_recent_erase(int node, time_stamp_t *ts);
+int sel_num_entries(int node);
+int sel_free_space(int node);
+int sel_rsv_id(int node);
+int sel_get_entry(int node, int read_rec_id, sel_msg_t *msg, int *next_rec_id);
+int sel_add_entry(int node, sel_msg_t *msg, int *rec_id);
+int sel_erase(int node, int rsv_id);
+int sel_erase_status(int node, int rsv_id, sel_erase_stat_t *status);
int sel_init(void);
#endif /* __SEL_H__ */
diff --git a/common/recipes-core/log-util/files/lib_pal.py b/common/recipes-core/log-util/files/lib_pal.py
new file mode 100644
index 0000000..dcae08a
--- /dev/null
+++ b/common/recipes-core/log-util/files/lib_pal.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+#
+
+from ctypes import *
+
+lpal_hndl = CDLL("libpal.so")
+
+def pal_get_fru_name(fru):
+ name = create_string_buffer(16)
+ ret = lpal_hndl.pal_get_fru_name(c_uint8(fru), name)
+ if ret:
+ return None
+ else:
+ return name.value
diff --git a/common/recipes-core/log-util/files/log-util.py b/common/recipes-core/log-util/files/log-util.py
new file mode 100644
index 0000000..565e9a1
--- /dev/null
+++ b/common/recipes-core/log-util/files/log-util.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+#
+
+import re
+from datetime import datetime
+import sys
+from ctypes import *
+from lib_pal import *
+
+SYSLOGFILE = '/mnt/data/logfile'
+APPNAME = 'log-util'
+
+def print_usage():
+ print 'Usage: %s --show' % (APPNAME)
+
+def log_main():
+
+ if len(sys.argv) is not 2:
+ print_usage()
+ return -1
+
+ if sys.argv[1] != '--show':
+ print_usage()
+ return -1
+
+ fd = open(SYSLOGFILE, 'r')
+ syslog = fd.readlines()
+ fd.close()
+
+ print '%-4s %-8s %-22s %-16s %s' % (
+ "FRU#",
+ "FRU_NAME",
+ "TIME_STAMP",
+ "APP_NAME",
+ "MESSAGE"
+ )
+
+ for log in syslog:
+ if not (re.search(r' bmc [a-z]*.crit ', log)):
+ continue
+ if re.search(r'FRU: [0-9]{1,2}', log, re.IGNORECASE):
+ fru = ''.join(re.findall(r'FRU: [0-9]{1,2}', log, re.IGNORECASE))
+ # fru is in format "FRU: X"
+ fru = fru[5]
+
+ # Name of the FRU from the PAL library
+ name = pal_get_fru_name(int(fru))
+ else :
+ fru = '0'
+
+ name = 'all'
+
+
+ temp = re.split(r' bmc [a-z]*.crit ', log)
+
+ # Time format Sep 28 22:10:50
+ ts = temp[0]
+ currtime = datetime.now()
+ ts = '%d %s' % (currtime.year, ts)
+ time = datetime.strptime(ts, '%Y %b %d %H:%M:%S')
+ time = time.strftime('%Y-%m-%d %H:%M:%S')
+
+ temp2 = re.split(r': ', temp[1], 1)
+ app = temp2[0]
+ message = temp2[1]
+
+ print '%-4s %-8s %-22s %-16s %s' % (
+ fru,
+ name,
+ time,
+ app,
+ message
+ )
+
+
+if __name__ == '__main__':
+ log_main()
diff --git a/common/recipes-core/log-util/log-util_0.1.bb b/common/recipes-core/log-util/log-util_0.1.bb
new file mode 100644
index 0000000..0782688
--- /dev/null
+++ b/common/recipes-core/log-util/log-util_0.1.bb
@@ -0,0 +1,57 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+SUMMARY = "Log Utility"
+DESCRIPTION = "Utility to parse and display logs."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://log-util.py;beginline=5;endline=18;md5=0b1ee7d6f844d472fa306b2fee2167e0"
+
+
+SRC_URI = "file://log-util.py \
+ file://lib_pal.py \
+ "
+
+S = "${WORKDIR}"
+
+DEPENDS += "libpal"
+
+binfiles = "log-util.py lib_pal.py"
+
+pkgdir = "log-util"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ install -d $dst
+ localbindir="${D}/usr/local/bin"
+ install -d ${localbindir}
+
+ install -m 755 log-util.py ${dst}/log-util
+ ln -s ../fbpackages/${pkgdir}/log-util ${localbindir}/log-util
+
+ install -m 755 lib_pal.py ${dst}/lib_pal.py
+ ln -s ../fbpackages/${pkgdir}/lib_pal.py ${localbindir}/lib_pal.py
+}
+
+RDEPENDS_${PN} += "libpal"
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/log-util ${prefix}/local/bin"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/power-util/files/power-util.c b/common/recipes-core/power-util/files/power-util.c
index 0fda9d6..07e7c23 100644
--- a/common/recipes-core/power-util/files/power-util.c
+++ b/common/recipes-core/power-util/files/power-util.c
@@ -32,8 +32,8 @@
#define POWER_ON_STR "on"
#define POWER_OFF_STR "off"
-const char *pwr_option_list = "status, graceful-shutdown, off, on, cycle, 12V-off,"
- "12V-on, 12V-cycle";
+const char *pwr_option_list = "status, graceful-shutdown, off, on, cycle, "
+ "12V-off, 12V-on, 12V-cycle";
enum {
PWR_STATUS = 1,
@@ -47,22 +47,6 @@ enum {
PWR_SLED_CYCLE
};
-static int
-set_last_pwr_state(uint8_t fru, char * state) {
-
- int ret;
- char key[MAX_KEY_LEN] = {0};
-
- sprintf(key, "pwr_server%d_last_state", (int) fru);
-
- ret = pal_set_key_value(key, state);
- if (ret < 0) {
- syslog(LOG_ALERT, "set_last_pwr_state: pal_set_key_value failed for "
- "fru %u", fru);
- }
- return ret;
-}
-
static void
print_usage() {
printf("Usage: power-util [ %s ] [ %s ]\nUsage: power-util sled-cycle\n",
@@ -107,7 +91,7 @@ power_util(uint8_t fru, uint8_t opt) {
case PWR_STATUS:
ret = pal_get_server_power(fru, &status);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_get_server_power failed for fru %u\n", fru);
+ syslog(LOG_WARNING, "power_util: pal_get_server_power failed for fru %u\n", fru);
return ret;
}
printf("Power status for fru %u : %s\n", fru, status?"ON":"OFF");
@@ -119,22 +103,24 @@ power_util(uint8_t fru, uint8_t opt) {
ret = pal_set_server_power(fru, SERVER_GRACEFUL_SHUTDOWN);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
" fru %u", fru);
return ret;
} else if (ret == 1) {
printf("fru %u is already powered OFF...\n", fru);
return 0;
+ } else {
+ syslog(LOG_CRIT, "SERVER_GRACEFUL_SHUTDOWN successful for FRU: %d", fru);
}
- ret = set_last_pwr_state(fru, POWER_OFF_STR);
+ ret = pal_set_last_pwr_state(fru, POWER_OFF_STR);
if (ret < 0) {
return ret;
}
ret = pal_set_led(fru, LED_STATE_OFF);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ syslog(LOG_WARNING, "power_util: pal_set_led failed for fru %u", fru);
return ret;
}
break;
@@ -145,22 +131,24 @@ power_util(uint8_t fru, uint8_t opt) {
ret = pal_set_server_power(fru, SERVER_POWER_OFF);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
" fru %u", fru);
return ret;
} else if (ret == 1) {
printf("fru %u is already powered OFF...\n", fru);
return 0;
+ } else {
+ syslog(LOG_CRIT, "SERVER_POWER_OFF successful for FRU: %d", fru);
}
- ret = set_last_pwr_state(fru, POWER_OFF_STR);
+ ret = pal_set_last_pwr_state(fru, POWER_OFF_STR);
if (ret < 0) {
return ret;
}
ret = pal_set_led(fru, LED_STATE_OFF);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ syslog(LOG_WARNING, "power_util: pal_set_led failed for fru %u", fru);
return ret;
}
break;
@@ -171,22 +159,24 @@ power_util(uint8_t fru, uint8_t opt) {
ret = pal_set_server_power(fru, SERVER_POWER_ON);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
" fru %u", fru);
return ret;
} else if (ret == 1) {
printf("fru %u is already powered ON...\n", fru);
return 0;
+ } else {
+ syslog(LOG_CRIT, "SERVER_POWER_ON successful for FRU: %d", fru);
}
- ret = set_last_pwr_state(fru, POWER_ON_STR);
+ ret = pal_set_last_pwr_state(fru, POWER_ON_STR);
if (ret < 0) {
return ret;
}
ret = pal_set_led(fru, LED_STATE_ON);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ syslog(LOG_WARNING, "power_util: pal_set_led failed for fru %u", fru);
return ret;
}
break;
@@ -197,41 +187,97 @@ power_util(uint8_t fru, uint8_t opt) {
ret = pal_set_server_power(fru, SERVER_POWER_CYCLE);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
" fru %u", fru);
return ret;
+ } else {
+ syslog(LOG_CRIT, "SERVER_POWER_CYCLE successful for FRU: %d", fru);
}
- ret = set_last_pwr_state(fru, POWER_ON_STR);
+ ret = pal_set_last_pwr_state(fru, POWER_ON_STR);
if (ret < 0) {
return ret;
}
ret = pal_set_led(fru, LED_STATE_ON);
if (ret < 0) {
- syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ syslog(LOG_WARNING, "power_util: pal_set_led failed for fru %u", fru);
return ret;
}
break;
case PWR_12V_OFF:
- ret = 0; // TODO: Need to add the API to support this power state setting
+
+ printf("12V Powering fru %u to OFF state...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_12V_OFF);
+ if (ret < 0) {
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ } else {
+ syslog(LOG_CRIT, "SERVER_12V_OFF successful for FRU: %d", fru);
+ }
+
+ ret = pal_set_last_pwr_state(fru, POWER_OFF_STR);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_set_led(fru, LED_STATE_OFF);
+ if (ret < 0) {
+ syslog(LOG_WARNING, "power_util: pal_set_led failed for fru %u", fru);
+ return ret;
+ }
break;
case PWR_12V_ON:
- ret = 0; // TODO: Need to add the API to support this power state setting
+
+ printf("12V Powering fru %u to ON state...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_12V_ON);
+ if (ret < 0) {
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ } else {
+ syslog(LOG_CRIT, "SERVER_12V_ON successful for FRU: %d", fru);
+ }
break;
case PWR_12V_CYCLE:
- ret = 0; // TODO: Need to add the API to support this power state setting
+
+ printf("12V Power cycling fru %u...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_12V_CYCLE);
+ if (ret < 0) {
+ syslog(LOG_WARNING, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ } else {
+ syslog(LOG_CRIT, "SERVER_12V_CYCLE successful for FRU: %d", fru);
+ }
+
+ ret = pal_set_last_pwr_state(fru, POWER_OFF_STR);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_set_led(fru, LED_STATE_OFF);
+ if (ret < 0) {
+ syslog(LOG_WARNING, "power_util: pal_set_led failed for fru %u", fru);
+ return ret;
+ }
break;
case PWR_SLED_CYCLE:
+ syslog(LOG_CRIT, "SLED_CYCLE successful");
+ sleep(1);
pal_sled_cycle();
break;
default:
- syslog(LOG_ALERT, "power_util: wrong option");
+ syslog(LOG_WARNING, "power_util: wrong option");
}
@@ -292,4 +338,6 @@ main(int argc, char **argv) {
print_usage();
return ret;
}
+
+ return ret;
}
diff --git a/common/recipes-core/python/python_2.7.9.bbappend b/common/recipes-core/python/python_2.7.9.bbappend
new file mode 100644
index 0000000..c3f1fa1
--- /dev/null
+++ b/common/recipes-core/python/python_2.7.9.bbappend
@@ -0,0 +1,21 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+# Patch from here - http://patchwork.openembedded.org/patch/96953/
+# is not available upstream yet . Until then we are adding ourselves to
+# satisfy ssl.py that has a dependency on this module.
+RDEPENDS_${PN}-io += "${PN}-contextlib"
diff --git a/common/recipes-core/sensor-mon/files/sensord.c b/common/recipes-core/sensor-mon/files/sensord.c
index 1852af3..0ad00f7 100644
--- a/common/recipes-core/sensor-mon/files/sensord.c
+++ b/common/recipes-core/sensor-mon/files/sensord.c
@@ -32,73 +32,17 @@
#include <facebook/bic.h>
#include <openbmc/ipmi.h>
#include <openbmc/sdr.h>
-#ifdef CONFIG_YOSEMITE
-#include <facebook/yosemite_sensor.h>
-#endif /* CONFIG_YOSEMITE */
-
-#define MAX_SENSOR_NUM 0xFF
-#define NORMAL_STATE 0x00
-
-#define SETBIT(x, y) (x | (1 << y))
-#define GETBIT(x, y) ((x & (1 << y)) > y)
-#define CLEARBIT(x, y) (x & (~(1 << y)))
-#define GETMASK(y) (1 << y)
-
-
-
-/* Enum for type of Upper and Lower threshold values */
-enum {
- UCR_THRESH = 0x01,
- UNC_THRESH,
- UNR_THRESH,
- LCR_THRESH,
- LNC_THRESH,
- LNR_THRESH,
- POS_HYST,
- NEG_HYST,
-};
-
-/* To hold the sensor info and calculated threshold values from the SDR */
-typedef struct {
- uint8_t flag;
- float ucr_thresh;
- float unc_thresh;
- float unr_thresh;
- float lcr_thresh;
- float lnc_thresh;
- float lnr_thresh;
- float pos_hyst;
- float neg_hyst;
- int curr_state;
- char name[23];
- char units[64];
-
-} thresh_sensor_t;
-
-/* Function pointer to read sensor current value */
-static int (*read_snr_val)(uint8_t, uint8_t, void *);
-
-#ifdef CONFIG_YOSEMITE
-
-// TODO: Change to 6 after adding SPB and NIC
-#define MAX_NUM_FRUS 4
-#define YOSEMITE_SDR_PATH "/tmp/sdr_%s.bin"
-
-static thresh_sensor_t snr_slot1[MAX_SENSOR_NUM] = {0};
-static thresh_sensor_t snr_slot2[MAX_SENSOR_NUM] = {0};
-static thresh_sensor_t snr_slot3[MAX_SENSOR_NUM] = {0};
-static thresh_sensor_t snr_slot4[MAX_SENSOR_NUM] = {0};
-static thresh_sensor_t snr_spb[MAX_SENSOR_NUM] = {0};
-static thresh_sensor_t snr_nic[MAX_SENSOR_NUM] = {0};
-
-static sensor_info_t sinfo_slot1[MAX_SENSOR_NUM] = {0};
-static sensor_info_t sinfo_slot2[MAX_SENSOR_NUM] = {0};
-static sensor_info_t sinfo_slot3[MAX_SENSOR_NUM] = {0};
-static sensor_info_t sinfo_slot4[MAX_SENSOR_NUM] = {0};
-static sensor_info_t sinfo_spb[MAX_SENSOR_NUM] = {0};
-static sensor_info_t sinfo_nic[MAX_SENSOR_NUM] = {0};
-#endif /* CONFIG_YOSEMITE */
+#include <openbmc/pal.h>
+#define DELAY 2
+
+static thresh_sensor_t g_snr[MAX_NUM_FRUS][MAX_SENSOR_NUM] = {0};
+
+static void
+print_usage() {
+ printf("Usage: sensord <options>\n");
+ printf("Options: [ %s ]\n", pal_fru_list);
+}
/*
* Returns the pointer to the struct holding all sensor info and
@@ -109,502 +53,58 @@ get_struct_thresh_sensor(uint8_t fru) {
thresh_sensor_t *snr;
-#ifdef CONFIG_YOSEMITE
- switch (fru) {
- case FRU_SLOT1:
- snr = snr_slot1;
- break;
- case FRU_SLOT2:
- snr = snr_slot2;
- break;
- case FRU_SLOT3:
- snr = snr_slot3;
- break;
- case FRU_SLOT4:
- snr = snr_slot4;
- break;
- case FRU_SPB:
- snr = snr_spb;
- break;
- case FRU_NIC:
- snr = snr_nic;
- break;
- default:
- syslog(LOG_ALERT, "get_struct_thresh_sensor: Wrong FRU ID %d\n", fru);
- return NULL;
- }
-#endif /* CONFIG_YOSEMITE */
-
- return snr;
-}
-
-
-/* Returns the all the SDRs for the particular fru# */
-static sensor_info_t *
-get_struct_sensor_info(uint8_t fru) {
-
- sensor_info_t *sinfo;
-
-#ifdef CONFIG_YOSEMITE
- switch (fru) {
- case FRU_SLOT1:
- sinfo = sinfo_slot1;
- break;
- case FRU_SLOT2:
- sinfo = sinfo_slot2;
- break;
- case FRU_SLOT3:
- sinfo = sinfo_slot3;
- break;
- case FRU_SLOT4:
- sinfo = sinfo_slot4;
- break;
- case FRU_SPB:
- sinfo = sinfo_spb;
- break;
- case FRU_NIC:
- sinfo = sinfo_nic;
- break;
- default:
- syslog(LOG_ALERT, "get_struct_sensor_info: Wrong FRU ID %d\n", fru);
- return NULL;
- }
-#endif /* CONFIG_YOSEMITE */
-
- return sinfo;
-}
-
-
-/* Returns the SDR for a particular sensor of particular fru# */
-static sdr_full_t *
-get_struct_sdr(uint8_t fru, uint8_t snr_num) {
-
- sdr_full_t *sdr;
- sensor_info_t *sinfo;
- sinfo = get_struct_sensor_info(fru);
- if (sinfo == NULL) {
- syslog(LOG_ALERT, "get_struct_sdr: get_struct_sensor_info failed\n");
+ if (fru < 1 || fru > MAX_NUM_FRUS) {
+ syslog(LOG_WARNING, "get_struct_thresh_sensor: Wrong FRU ID %d\n", fru);
return NULL;
}
- sdr = &sinfo[snr_num].sdr;
- return sdr;
+ snr = g_snr[fru-1];
+ return snr;
}
-/* Get the threshold values from the SDRs */
+/* Initialize all thresh_sensor_t structs for all the Yosemite sensors */
static int
-get_sdr_thresh_val(uint8_t fru, uint8_t snr_num, uint8_t thresh, void *value) {
+init_fru_snr_thresh(uint8_t fru) {
+ int i;
int ret;
- uint8_t x;
- uint8_t m_lsb, m_msb, m;
- uint8_t b_lsb, b_msb, b;
- int8_t b_exp, r_exp;
- uint8_t thresh_val;
- sdr_full_t *sdr;
-
- sdr = get_struct_sdr(fru, snr_num);
- if (sdr == NULL) {
- syslog(LOG_ALERT, "get_sdr_thresh_val: get_struct_sdr failed\n");
- return -1;
- }
-
- switch (thresh) {
- case UCR_THRESH:
- thresh_val = sdr->uc_thresh;
- break;
- case UNC_THRESH:
- thresh_val = sdr->unc_thresh;
- break;
- case UNR_THRESH:
- thresh_val = sdr->unr_thresh;
- break;
- case LCR_THRESH:
- thresh_val = sdr->lc_thresh;
- break;
- case LNC_THRESH:
- thresh_val = sdr->lnc_thresh;
- break;
- case LNR_THRESH:
- thresh_val = sdr->lnr_thresh;
- break;
- case POS_HYST:
- thresh_val = sdr->pos_hyst;
- break;
- case NEG_HYST:
- thresh_val = sdr->neg_hyst;
- break;
- default:
- syslog(LOG_ERR, "get_sdr_thresh_val: reading unknown threshold val");
- return -1;
- }
-
- // y = (mx + b * 10^b_exp) * 10^r_exp
- x = thresh_val;
-
- m_lsb = sdr->m_val;
- m_msb = sdr->m_tolerance >> 6;
- m = (m_msb << 8) | m_lsb;
-
- b_lsb = sdr->b_val;
- b_msb = sdr->b_accuracy >> 6;
- b = (b_msb << 8) | b_lsb;
-
- // exponents are 2's complement 4-bit number
- b_exp = sdr->rb_exp & 0xF;
- if (b_exp > 7) {
- b_exp = (~b_exp + 1) & 0xF;
- b_exp = -b_exp;
- }
- r_exp = (sdr->rb_exp >> 4) & 0xF;
- if (r_exp > 7) {
- r_exp = (~r_exp + 1) & 0xF;
- r_exp = -r_exp;
- }
-
- * (float *) value = ((m * x) + (b * pow(10, b_exp))) * (pow(10, r_exp));
-
- return 0;
-}
-
-/*
- * Populate all fields of thresh_sensor_t struct for a particular sensor.
- * Incase the threshold value is 0 mask the check for that threshvold
- * value in flag field.
- */
-int
-init_snr_thresh(uint8_t fru, uint8_t snr_num, uint8_t flag) {
-
- int value;
- float fvalue;
- uint8_t op, modifier;
+ uint8_t snr_num;
+ int sensor_cnt;
+ uint8_t *sensor_list;
thresh_sensor_t *snr;
- sdr_full_t *sdr;
-
- sdr = get_struct_sdr(fru, snr_num);
- if (sdr == NULL) {
- syslog(LOG_ALERT, "init_snr_name: get_struct_sdr failed\n");
- return -1;
- }
-
snr = get_struct_thresh_sensor(fru);
if (snr == NULL) {
- syslog(LOG_ALERT, "init_snr_thresh: get_struct_thresh_sensor failed");
- return -1;
- }
-
- snr[snr_num].flag = flag;
- snr[snr_num].curr_state = NORMAL_STATE;
-
- if (sdr_get_sensor_name(sdr, snr[snr_num].name)) {
- syslog(LOG_ALERT, "sdr_get_sensor_name: FRU %d: num: 0x%X: reading name"
- " from SDR failed.", fru, snr_num);
- return -1;
- }
-
- // TODO: Add support for modifier (Mostly modifier is zero)
- if (sdr_get_sensor_units(sdr, &op, &modifier, snr[snr_num].units)) {
- syslog(LOG_ALERT, "sdr_get_sensor_units: FRU %d: num 0x%X: reading units"
- " from SDR failed.", fru, snr_num);
+#ifdef DEBUG
+ syslog(LOG_WARNING, "init_fru_snr_thresh: get_struct_thresh_sensor failed");
+#endif /* DEBUG */
return -1;
}
- if (get_sdr_thresh_val(fru, snr_num, UCR_THRESH, &fvalue)) {
- syslog(LOG_ERR,
- "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UCR_THRESH",
- fru, snr_num, snr[snr_num].name);
- } else {
- snr[snr_num].ucr_thresh = fvalue;
- if (!(fvalue)) {
- snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, UCR_THRESH);
- syslog(LOG_ALERT,
- "FRU: %d, num: 0x%X, %-16s, UCR_THRESH check disabled val->%.2f",
- fru, snr_num, snr[snr_num].name, fvalue);
- }
+ ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
+ if (ret < 0) {
+ return ret;
}
- if (get_sdr_thresh_val(fru, snr_num, UNC_THRESH, &fvalue)) {
- syslog(LOG_ERR,
- "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UNC_THRESH",
- fru, snr_num, snr[snr_num].name);
- } else {
- snr[snr_num].unc_thresh = fvalue;
- if (!(fvalue)) {
- snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, UNC_THRESH);
- syslog(LOG_ALERT,
- "FRU: %d, num: 0x%X, %-16s, UNC_THRESH check disabled val->%.2f",
- fru, snr_num, snr[snr_num].name, fvalue);
- }
- }
-
- if (get_sdr_thresh_val(fru, snr_num, UNR_THRESH, &fvalue)) {
- syslog(LOG_ERR,
- "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UNR_THRESH",
- fru, snr_num, snr[snr_num].name);
- } else {
- snr[snr_num].unr_thresh = fvalue;
- if (!(fvalue)) {
- snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, UNR_THRESH);
- syslog(LOG_ALERT,
- "FRU: %d, num: 0x%X, %-16s, UNR_THRESH check disabled val->%.2f",
- fru, snr_num, snr[snr_num].name, fvalue);
- }
- }
-
- if (get_sdr_thresh_val(fru, snr_num, LCR_THRESH, &fvalue)) {
- syslog(LOG_ERR,
- "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LCR_THRESH",
- fru, snr_num, snr[snr_num].name);
- } else {
- snr[snr_num].lcr_thresh = fvalue;
- if (!(fvalue)) {
- snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, LCR_THRESH);
- syslog(LOG_ALERT,
- "FRU: %d, num: 0x%X, %-16s, LCR_THRESH check disabled val->%.2f",
- fru, snr_num, snr[snr_num].name, fvalue);
- }
- }
-
- if (get_sdr_thresh_val(fru, snr_num, LNC_THRESH, &fvalue)) {
- syslog(LOG_ERR,
- "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LNC_THRESH",
- fru, snr_num, snr[snr_num].name);
- } else {
- snr[snr_num].lnc_thresh = fvalue;
- if (!(fvalue)) {
- snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, LNC_THRESH);
- syslog(LOG_ALERT,
- "FRU: %d, num: 0x%X, %-16s, LNC_THRESH check disabled val->%.2f",
- fru, snr_num, snr[snr_num].name, fvalue);
+ for (i < 0; i < sensor_cnt; i++) {
+ snr_num = sensor_list[i];
+ ret = sdr_get_snr_thresh(fru, snr_num,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH), &snr[snr_num]);
+ if (ret < 0) {
+#ifdef DEBUG
+ syslog(LOG_WARNING, "init_fru_snr_thresh: sdr_get_snr_thresh for FRU: %d", fru);
+#endif /* DEBUG */
+ continue;
}
}
- if (get_sdr_thresh_val(fru, snr_num, LNR_THRESH, &fvalue)) {
- syslog(LOG_ERR,
- "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LNR_THRESH",
- fru, snr_num, snr[snr_num].name);
- } else {
- snr[snr_num].lnr_thresh = fvalue;
- if (!(fvalue)) {
- snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, LNR_THRESH);
- syslog(LOG_ALERT,
- "FRU: %d, num: 0x%X, %-16s, LNR_THRESH check disabled val->%.2f",
- fru, snr_num, snr[snr_num].name, fvalue);
- }
+ // TODO: This is a HACK. Need to add the pal_threshold_verify support
+ if (fru > 0 && fru < 5) {
+ snr[BIC_SENSOR_SOC_THERM_MARGIN].flag = SETBIT(snr[BIC_SENSOR_SOC_THERM_MARGIN].flag, UCR_THRESH);
}
- if (get_sdr_thresh_val(fru, snr_num, POS_HYST, &fvalue)) {
- syslog(LOG_ERR, "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, POS_HYST",
- fru, snr_num, snr[snr_num].name);
- } else
- snr[snr_num].pos_hyst = fvalue;
-
- if (get_sdr_thresh_val(fru, snr_num, NEG_HYST, &fvalue)) {
- syslog(LOG_ERR, "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, NEG_HYST",
- fru, snr_num, snr[snr_num].name);
- } else
- snr[snr_num].neg_hyst = fvalue;
-
return 0;
}
-#ifdef CONFIG_YOSEMITE
-/* Initialize all thresh_sensor_t structs for all the Yosemite sensors */
-static void
-init_yosemite_snr_thresh(uint8_t fru) {
-
- int i;
-
- switch (fru) {
- case FRU_SLOT1:
- case FRU_SLOT2:
- case FRU_SLOT3:
- case FRU_SLOT4:
-
- for (i < 0; i < bic_sensor_cnt; i++) {
- init_snr_thresh(fru, bic_sensor_list[i], GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
- }
- /*
- init_snr_thresh(fru, BIC_SENSOR_MB_OUTLET_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_1V05PCH_VR_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_MB_INLET_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_PCH_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_THERM_MARGIN, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_CURR, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_1V05_PCH_VR_CURR, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_POUT, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_CURR, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_VOL,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_INA230_POWER, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_PACKAGE_PWR, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_TJMAX, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_POUT, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_CURR, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_VOL,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_CURR, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_VOL,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_POUT, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_POUT, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_VOL,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_1V05_PCH_VR_VOL,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMA0_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMA1_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMB0_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMB1_TEMP, GETMASK(UCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_P3V3_MB,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_P12V_MB,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_P1V05_PCH,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_P3V3_STBY_MB,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_P5V_STBY_MB,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_PV_BAT,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_PVDDR,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
-
- init_snr_thresh(fru, BIC_SENSOR_PVCC_GBE,
- GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
- // TODO: Add Support for Discrete sensors
- // init_snr_thresh(fru, BIC_SENSOR_POST_ERR, //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_SYSTEM_STATUS, //Discrete
- // init_snr_thresh(fru, BIC_SENSOR_SPS_FW_HLTH); //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_POWER_THRESH_EVENT, //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_MACHINE_CHK_ERR, //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_PCIE_ERR); //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_OTHER_IIO_ERR); //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_PROC_HOT_EXT); //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_POWER_ERR); //Event-only
- // init_snr_thresh(fru, , ); //Event-only
- // init_snr_thresh(fru, BIC_SENSOR_PROC_FAIL); //Discrete
- // init_snr_thresh(fru, BIC_SENSOR_SYS_BOOT_STAT ); //Discrete
- // init_snr_thresh(fru, BIC_SENSOR_VR_HOT); //Discrete
- // init_snr_thresh(fru, BIC_SENSOR_CPU_DIMM_HOT ); //Discrete
- // init_snr_thresh(fru, BIC_SENSOR_CAT_ERR, //Event-only
-
- */
-
- break;
-
- case FRU_SPB:
- // TODO: Add support for threshold calculation for SP sensors
- /*
- init_snr_thresh(fru, SP_SENSOR_INLET_TEMP, "SP_SENSOR_INLET_TEMP");
- init_snr_thresh(fru, SP_SENSOR_OUTLET_TEMP, "SP_SENSOR_OUTLET_TEMP");
- init_snr_thresh(fru, SP_SENSOR_MEZZ_TEMP, "SP_SENSOR_MEZZ_TEMP");
- init_snr_thresh(fru, SP_SENSOR_FAN0_TACH, "SP_SENSOR_FAN0_TACH");
- init_snr_thresh(fru, SP_SENSOR_FAN1_TACH, "SP_SENSOR_FAN1_TACH");
- init_snr_thresh(fru, SP_SENSOR_AIR_FLOW, "SP_SENSOR_AIR_FLOW");
- init_snr_thresh(fru, SP_SENSOR_P5V, "SP_SENSOR_P5V");
- init_snr_thresh(fru, SP_SENSOR_P12V, "SP_SENSOR_P12V");
- init_snr_thresh(fru, SP_SENSOR_P3V3_STBY, "SP_SENSOR_P3V3_STBY");
- init_snr_thresh(fru, SP_SENSOR_P12V_SLOT0, "SP_SENSOR_P12V_SLOT0");
- init_snr_thresh(fru, SP_SENSOR_P12V_SLOT1, "SP_SENSOR_P12V_SLOT1");
- init_snr_thresh(fru, SP_SENSOR_P12V_SLOT2, "SP_SENSOR_P12V_SLOT2");
- init_snr_thresh(fru, SP_SENSOR_P12V_SLOT3, "SP_SENSOR_P12V_SLOT3");
- init_snr_thresh(fru, SP_SENSOR_P3V3, "SP_SENSOR_P3V3");
- init_snr_thresh(fru, SP_SENSOR_HSC_IN_VOLT, "SP_SENSOR_HSC_IN_VOLT");
- init_snr_thresh(fru, SP_SENSOR_HSC_OUT_CURR, "SP_SENSOR_HSC_OUT_CURR");
- init_snr_thresh(fru, SP_SENSOR_HSC_TEMP, "SP_SENSOR_HSC_TEMP");
- init_snr_thresh(fru, SP_SENSOR_HSC_IN_POWER, "SP_SENSOR_HSC_IN_POWER");
- */
- break;
-
- case FRU_NIC:
- // TODO: Add support for NIC sensor threshold, if any.
- break;
-
- default:
- syslog(LOG_ALERT, "init_yosemite_snr_thresh: wrong FRU ID");
- exit(-1);
- }
-}
-#endif /* CONFIG_YOSEMITE */
-
-/* Wrapper function to initialize all the platform sensors */
-static void
-init_all_snr_thresh() {
- int fru;
-
- char path[64] = {0};
- sensor_info_t *sinfo;
-
-
-#ifdef CONFIG_YOSEMITE
- for (fru = FRU_SLOT1; fru < (FRU_SLOT1 + MAX_NUM_FRUS); fru++) {
-
- if (get_fru_sdr_path(fru, path) < 0) {
- syslog(LOG_ALERT, "yosemite_sdr_init: get_fru_sdr_path failed\n");
- continue;
- }
-#endif /* CONFIG_YOSEMITE */
-
- sinfo = get_struct_sensor_info(fru);
-
- if (sdr_init(path, sinfo) < 0)
- syslog(LOG_ERR, "init_all_snr_thresh: sdr_init failed for FRU %d", fru);
- }
-
-#ifdef CONFIG_YOSEMITE
- for (fru = FRU_SLOT1; fru < (FRU_SLOT1 + MAX_NUM_FRUS); fru++) {
- init_yosemite_snr_thresh(fru);
- }
-#endif /* CONFIG_YOSEMITE */
-}
-
-
-
-
static float
get_snr_thresh_val(uint8_t fru, uint8_t snr_num, uint8_t thresh) {
@@ -633,7 +133,7 @@ get_snr_thresh_val(uint8_t fru, uint8_t snr_num, uint8_t thresh) {
val = snr[snr_num].lnr_thresh;
break;
default:
- syslog(LOG_ALERT, "get_snr_thresh_val: wrong thresh enum value");
+ syslog(LOG_WARNING, "get_snr_thresh_val: wrong thresh enum value");
exit(-1);
}
@@ -662,7 +162,7 @@ check_thresh_deassert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
switch (thresh) {
case UNC_THRESH:
- if (curr_val <= thresh_val) {
+ if (curr_val < (thresh_val - snr[snr_num].pos_hyst)) {
curr_state = ~(SETBIT(curr_state, UNR_THRESH) |
SETBIT(curr_state, UCR_THRESH) |
SETBIT(curr_state, UNC_THRESH));
@@ -671,7 +171,7 @@ check_thresh_deassert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
break;
case UCR_THRESH:
- if (curr_val <= thresh_val) {
+ if (curr_val < (thresh_val - snr[snr_num].pos_hyst)) {
curr_state = ~(SETBIT(curr_state, UCR_THRESH) |
SETBIT(curr_state, UNR_THRESH));
sprintf(thresh_name, "Upper Critical");
@@ -679,14 +179,14 @@ check_thresh_deassert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
break;
case UNR_THRESH:
- if (curr_val <= thresh_val) {
+ if (curr_val < (thresh_val - snr[snr_num].pos_hyst)) {
curr_state = ~(SETBIT(curr_state, UNR_THRESH));
sprintf(thresh_name, "Upper Non Recoverable");
}
break;
case LNC_THRESH:
- if (curr_val >= thresh_val) {
+ if (curr_val > (thresh_val + snr[snr_num].neg_hyst)) {
curr_state = ~(SETBIT(curr_state, LNR_THRESH) |
SETBIT(curr_state, LCR_THRESH) |
SETBIT(curr_state, LNC_THRESH));
@@ -695,7 +195,7 @@ check_thresh_deassert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
break;
case LCR_THRESH:
- if (curr_val >= thresh_val) {
+ if (curr_val > (thresh_val + snr[snr_num].neg_hyst)) {
curr_state = ~(SETBIT(curr_state, LCR_THRESH) |
SETBIT(curr_state, LNR_THRESH));
sprintf(thresh_name, "Lower Critical");
@@ -703,23 +203,23 @@ check_thresh_deassert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
break;
case LNR_THRESH:
- if (curr_val >= thresh_val) {
+ if (curr_val > (thresh_val + snr[snr_num].neg_hyst)) {
curr_state = ~(SETBIT(curr_state, LNR_THRESH));
sprintf(thresh_name, "Lower Non Recoverable");
}
break;
default:
- syslog(LOG_ALERT, "get_snr_thresh_val: wrong thresh enum value");
+ syslog(LOG_WARNING, "get_snr_thresh_val: wrong thresh enum value");
exit(-1);
}
if (curr_state) {
snr[snr_num].curr_state &= curr_state;
- syslog(LOG_CRIT, "DEASSERT: %s threshold raised - FRU: %d, num: 0x%X,"
- " snr: %-16s,",thresh_name, fru, snr_num, snr[snr_num].name);
- syslog(LOG_CRIT, "curr_val: %.2f %s, thresh_val: %.2f %s cf: %u",
- curr_val, snr[snr_num].units, thresh_val, snr[snr_num].units, snr[snr_num].curr_state);
+ syslog(LOG_CRIT, "DEASSERT: %s threshold - settled - FRU: %d, num: 0x%X "
+ "curr_val: %.2f %s, thresh_val: %.2f %s, snr: %-16s",thresh_name,
+ fru, snr_num,curr_val, snr[snr_num].units, thresh_val,
+ snr[snr_num].units, snr[snr_num].name);
}
}
@@ -794,17 +294,99 @@ check_thresh_assert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
break;
default:
- syslog(LOG_ALERT, "get_snr_thresh_val: wrong thresh enum value");
+ syslog(LOG_WARNING, "get_snr_thresh_val: wrong thresh enum value");
exit(-1);
}
if (curr_state) {
curr_state &= snr[snr_num].flag;
snr[snr_num].curr_state |= curr_state;
- syslog(LOG_CRIT, "ASSERT: %s threshold raised - FRU: %d, num: 0x%X,"
- " snr: %-16s,",thresh_name, fru, snr_num, snr[snr_num].name);
- syslog(LOG_CRIT, "curr_val: %.2f %s, thresh_val: %.2f %s cf: %u",
- curr_val, snr[snr_num].units, thresh_val, snr[snr_num].units, snr[snr_num].curr_state);
+ syslog(LOG_CRIT, "ASSERT: %s threshold - raised - FRU: %d, num: 0x%X"
+ " curr_val: %.2f %s, thresh_val: %.2f %s, snr: %-16s", thresh_name,
+ fru, snr_num, curr_val, snr[snr_num].units, thresh_val,
+ snr[snr_num].units, snr[snr_num].name);
+ }
+}
+
+
+/*
+ * Starts monitoring all the sensors on a fru for all discrete sensors.
+ * Each pthread runs this monitoring for a different fru.
+ */
+static void *
+snr_discrete_monitor(void *arg) {
+
+#ifdef DEBUG2
+ char tmplog[1000];
+#endif /* DEBUG2 */
+ uint8_t fru = *(uint8_t *) arg;
+ int i, ret;
+ uint8_t discrete_cnt;
+ uint8_t snr_num;
+ //uint8_t *discrete_list;
+ thresh_sensor_t *snr;
+ float normal_val, curr_val;
+
+ // TODO: Need to resolve the SEGFAULT in the call below and replace HACK here.
+ /*
+ ret = pal_get_fru_discrete_list(fru, &discrete_list, &discrete_cnt);
+ if (ret < 0) {
+ return;
+ }
+ */
+ /* HACK */
+ uint8_t discrete_list[3];
+ if (fru != FRU_SPB && fru != FRU_NIC) {
+ discrete_list[0] = BIC_SENSOR_SYSTEM_STATUS;
+ discrete_list[1] = BIC_SENSOR_VR_HOT;
+ discrete_list[2] = BIC_SENSOR_CPU_DIMM_HOT;
+ } else {
+ return -1;
+ }
+
+ discrete_cnt = 3;
+
+ snr = get_struct_thresh_sensor(fru);
+ if (snr == NULL) {
+ syslog(LOG_WARNING, "snr_thresh_monitor: get_struct_thresh_sensor failed");
+ exit(-1);
+ }
+
+ for (i = 0; i < discrete_cnt; i++) {
+ snr_num = discrete_list[i];
+ pal_get_sensor_name(fru, snr_num, snr[snr_num].name);
+ }
+
+#if defined(TESTING) || defined(DEBUG)
+ int cnt = 0;
+#endif
+ while(1) {
+ for (i = 0; i < discrete_cnt; i++) {
+ snr_num = discrete_list[i];
+ ret = pal_sensor_read(fru, snr_num, &curr_val);
+
+#ifdef DEBUG2
+ sprintf(tmplog, "echo 0x%X %s %d >> /tmp/discretetest%d", snr_num, snr[snr_num].name, (int) curr_val, fru);
+ system(tmplog);
+#endif /* DEBUG2 */
+
+#if defined(TESTING) || defined(DEBUG)
+ if (cnt == 2 && snr_num == BIC_SENSOR_SYSTEM_STATUS) {
+ curr_val = ((int) curr_val) | 0x1;
+ } else if (cnt == 6 && snr_num == BIC_SENSOR_SYSTEM_STATUS) {
+ curr_val = ((int) curr_val) & 0x0;
+ }
+#endif
+ if ((snr[snr_num].curr_state != (int) curr_val) && !ret) {
+ pal_sensor_discrete_check(fru, snr_num, snr[snr_num].name,
+ snr[snr_num].curr_state, (int) curr_val);
+ snr[snr_num].curr_state = (int) curr_val;
+ }
+ }
+#if defined(TESTING) || defined(DEBUG)
+ cnt ++;
+#endif
+ sleep(DELAY);
}
}
@@ -813,24 +395,28 @@ check_thresh_assert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
* Each pthread runs this monitoring for a different fru.
*/
static void *
-snr_monitor(void *arg) {
+snr_thresh_monitor(void *arg) {
uint8_t fru = *(uint8_t *) arg;
int f, ret, snr_num;
float normal_val, curr_val;
thresh_sensor_t *snr;
-#ifdef TESTING
+#if defined(TESTING) || defined(DEBUG)
float temp_thresh;
int cnt = 0;
#endif /* TESTING */
snr = get_struct_thresh_sensor(fru);
if (snr == NULL) {
- syslog(LOG_ALERT, "snr_monitor: get_struct_thresh_sensor failed");
+ syslog(LOG_WARNING, "snr_thresh_monitor: get_struct_thresh_sensor failed");
exit(-1);
}
+#ifdef DEBUG2
+ char tmplog[1000];
+#endif /* DEBUG2 */
+
while(1) {
#ifdef TESTING
@@ -840,8 +426,11 @@ snr_monitor(void *arg) {
for (snr_num = 0; snr_num < MAX_SENSOR_NUM; snr_num++) {
curr_val = 0;
if (snr[snr_num].flag) {
- if (!(ret = read_snr_val(fru, snr_num, &curr_val))) {
-
+ if (!(ret = pal_sensor_read(fru, snr_num, &curr_val))) {
+#ifdef DEBUG2
+ sprintf(tmplog, "echo 0x%X %s %.2f >> /tmp/analog%d", snr_num, snr[snr_num].name, curr_val, fru);
+ system(tmplog);
+#endif /* DEBUG2 */
#ifdef TESTING
/*
@@ -871,7 +460,6 @@ snr_monitor(void *arg) {
snr[snr_num].units);
}
#endif /* DEBUG */
-
check_thresh_assert(fru, snr_num, UNR_THRESH, curr_val);
check_thresh_assert(fru, snr_num, UCR_THRESH, curr_val);
check_thresh_assert(fru, snr_num, UNC_THRESH, curr_val);
@@ -885,117 +473,149 @@ snr_monitor(void *arg) {
check_thresh_deassert(fru, snr_num, LNC_THRESH, curr_val);
check_thresh_deassert(fru, snr_num, LCR_THRESH, curr_val);
check_thresh_deassert(fru, snr_num, LNR_THRESH, curr_val);
-
} else {
/*
- * Incase the read_snr_val failed for a sensor,
+ * Incase the pal_sensor_read failed for a sensor,
* disable all the threshold checks for that sensor
* after logging an approciate syslog message.
*/
+ if (ret == ERR_NOT_READY) {
+ continue;
+ }
+
if (ret) {
+#ifdef DEBUG
syslog(LOG_ERR, "FRU: %d, num: 0x%X, snr:%-16s, read failed",
fru, snr_num, snr[snr_num].name);
- syslog(LOG_ERR, "FRU: %d, num: 0x%X, snr:%-16s, check disabled",
- fru, snr_num, snr[snr_num].name);
- snr[snr_num].flag = 0;
- //}
+#endif
+
+ /*
+ * Check if the fru is up and running before disabling the sensor.
+ * If the fru is powered down, DO NOT disable the sensor check.
+ */
+ char state[MAX_VALUE_LEN];
+
+ pal_get_last_pwr_state(fru, state);
+ if (!strcmp(state, "on")) {
+ snr[snr_num].flag = 0;
+ syslog(LOG_ERR, "FRU: %d, num: 0x%X, snr:%-16s, check disabled",
+ fru, snr_num, snr[snr_num].name);
+ }
}
- } /* read_snr_val return check */
+ } /* pal_sensor_read return check */
} /* flag check */
} /* loop for all sensors */
- sleep(5);
+ sleep(DELAY);
} /* while loop*/
} /* function definition */
+#ifdef DEBUG
+void print_snr_thread(uint8_t fru, thresh_sensor_t *snr)
+{
+ int i,j;
+ float curr_val;
+ char tmplog[1000];
+ char print[1000];
+
+ for (i = 0; i <= MAX_SENSOR_NUM; i++) {
+ if (snr[i].flag) {
+ curr_val = 0;
+ if(!(pal_sensor_read(fru, i, &curr_val))) {
+ sprintf(tmplog, "%-30s: %s %.2f %.2f %.2f %.2f\n",
+ snr[i].name, snr[i].units,
+ snr[i].ucr_thresh,
+ snr[i].lcr_thresh,
+ snr[i].pos_hyst,
+ snr[i].neg_hyst);
+ sprintf(print, "echo %s >> /tmp/print%d", tmplog, fru);
+ system(print);
+ }
+ }
+ }
+}
+#endif /* DEBUG */
+
/* Spawns a pthread for each fru to monitor all the sensors on it */
-static void
+static int
run_sensord(int argc, char **argv) {
- int i, arg;
+ int ret, arg;
+ uint8_t fru;
+ uint8_t fru_flag = 0;
pthread_t thread_snr[MAX_NUM_FRUS];
- int fru[MAX_NUM_FRUS] = {0};
-
- for (arg = 1; arg < argc; arg ++) {
-#ifdef CONFIG_YOSEMITE
- if (!(strcmp(argv[arg], "slot1")))
- fru[FRU_SLOT1 - 1] = FRU_SLOT1;
- else if (!(strcmp(argv[arg], "slot2")))
- fru[FRU_SLOT2 - 1] = FRU_SLOT2;
- else if (!(strcmp(argv[arg], "slot3")))
- fru[FRU_SLOT3 - 1] = FRU_SLOT3;
- else if (!(strcmp(argv[arg], "slot4")))
- fru[FRU_SLOT4 - 1] = FRU_SLOT4;
- else if (!(strcmp(argv[arg], "spb")))
- fru[FRU_SPB - 1] = FRU_SPB;
- else if (!(strcmp(argv[arg], "nic")))
- fru[FRU_NIC - 1] = FRU_NIC;
- else {
- syslog(LOG_ALERT, "Wrong argument: %s", argv[arg]);
- exit(1);
- }
-#endif /* CONFIG_YOSEMITE */
+ pthread_t discrete_snr[MAX_NUM_FRUS];
+
+ arg = 1;
+ while(arg < argc) {
+ ret = pal_get_fru_id(argv[arg], &fru);
+ if (ret < 0)
+ return ret;
+
+ fru_flag = SETBIT(fru_flag, fru);
+ arg++;
}
- for (i = 0; i < MAX_NUM_FRUS; i++) {
- if (fru[i]) {
- if (pthread_create(&thread_snr[i], NULL, snr_monitor,
- (void*) &fru[i]) < 0) {
- syslog(LOG_ALERT, "pthread_create for FRU %d failed\n", fru[i]);
+ for (fru = 1; fru <= MAX_NUM_FRUS; fru++) {
+
+ if (GETBIT(fru_flag, fru)) {
+
+ if (init_fru_snr_thresh(fru))
+ return ret;
+
+ /* Threshold Sensors */
+ if (pthread_create(&thread_snr[fru-1], NULL, snr_thresh_monitor,
+ (void*) &fru) < 0) {
+ syslog(LOG_WARNING, "pthread_create for FRU %d failed\n", fru);
}
#ifdef DEBUG
else {
- syslog(LOG_ALERT, "pthread_create for FRU %d succeed\n", fru[i]);
+ syslog(LOG_WARNING, "pthread_create for FRU %d succeed\n", fru);
}
#endif /* DEBUG */
+ sleep(1);
+
+ /* Discrete Sensors */
+ if (pthread_create(&discrete_snr[fru-1], NULL, snr_discrete_monitor,
+ (void*) &fru) < 0) {
+ syslog(LOG_WARNING, "pthread_create for FRU %d failed\n", fru);
+ }
+#ifdef DEBUG
+ else {
+ syslog(LOG_WARNING, "pthread_create for discrete FRU %d succeed\n", fru);
+ }
+#endif /* DEBUG */
+ sleep(1);
}
- sleep(1);
}
- for (i = 0; i < MAX_NUM_FRUS; i++) {
- if (fru[i])
- pthread_join(thread_snr[i], NULL);
- }
-}
+#ifdef DEBUG
+ int i;
+ for (i = 1; i <= MAX_NUM_FRUS; i++)
+ print_snr_thread(i, g_snr[i-1]);
+#endif /* DEBUG */
+ for (fru = 1; fru <= MAX_NUM_FRUS; fru++) {
-#ifdef DEBUG
-void print_snr_thread(uint8_t fru, thresh_sensor_t *snr)
-{
- int i;
- float curr_val;
+ if (GETBIT(fru_flag, fru))
+ pthread_join(discrete_snr[fru-1], NULL);
+ }
- for (i = 1; i <= MAX_SENSOR_NUM; i++) {
- if (snr[i].flag) {
- curr_val = 0;
- if(!(read_snr_val(fru, i, &curr_val))) {
- printf("%-30s:\t%.2f %s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n",
- snr[i].name, curr_val,snr[i].units,
- snr[i].ucr_thresh,
- snr[i].unc_thresh,
- snr[i].lcr_thresh,
- snr[i].lnr_thresh,
- snr[i].pos_hyst,
- snr[i].neg_hyst);
- } else
- printf("Reading failed: %-16s\n", snr[i].name);
- }
+ for (fru = 1; fru <= MAX_NUM_FRUS; fru++) {
+
+ if (GETBIT(fru_flag, fru))
+ pthread_join(thread_snr[fru-1], NULL);
}
}
-#endif /* DEBUG */
+
int
main(int argc, void **argv) {
int dev, rc, pid_file;
if (argc < 2) {
- syslog(LOG_ALERT, "Usage: sensord <options>");
- printf("Usage: sensord <options>\n");
-#ifdef CONFIG_YOSEMITE
- syslog(LOG_ALERT, "Options: [slot1 | slot2 | slot3 | slot4 | spb | nic]");
- printf("Options: [slot1 | slot2 | slot3 | slot4 | spb | nic]\n");
-#endif /* CONFIG_YOSEMITE */
+ print_usage();
exit(1);
}
@@ -1008,24 +628,15 @@ main(int argc, void **argv) {
}
} else {
-#ifdef CONFIG_YOSEMITE
- read_snr_val = &yosemite_sensor_read;
-#endif /* CONFIG_YOSEMITE */
-
- init_all_snr_thresh();
-
-#ifdef DEBUG
- print_snr_thread(1, snr_slot1);
- print_snr_thread(2, snr_slot2);
- print_snr_thread(3, snr_slot3);
- print_snr_thread(4, snr_slot4);
-#endif /* DEBUG */
-
daemon(0,1);
openlog("sensord", LOG_CONS, LOG_DAEMON);
syslog(LOG_INFO, "sensord: daemon started");
- run_sensord(argc, (char **) argv);
- }
+ rc = run_sensord(argc, (char **) argv);
+ if (rc < 0) {
+ print_usage();
+ return -1;
+ }
+ }
return 0;
}
diff --git a/common/recipes-core/sensor-mon/sensor-mon_0.1.bb b/common/recipes-core/sensor-mon/sensor-mon_0.1.bb
index adbd4cb..2cd2e4d 100644
--- a/common/recipes-core/sensor-mon/sensor-mon_0.1.bb
+++ b/common/recipes-core/sensor-mon/sensor-mon_0.1.bb
@@ -31,9 +31,9 @@ S = "${WORKDIR}"
binfiles = "sensord \
"
-CFLAGS += " -lsdr "
+CFLAGS += " -lsdr -lpal "
-DEPENDS += " libsdr "
+DEPENDS += " libpal libsdr "
pkgdir = "sensor-mon"
diff --git a/common/recipes-core/sensor-util/files/Makefile b/common/recipes-core/sensor-util/files/Makefile
index 2d39a04..168e4d7 100644
--- a/common/recipes-core/sensor-util/files/Makefile
+++ b/common/recipes-core/sensor-util/files/Makefile
@@ -3,7 +3,7 @@ all: sensor-util
sensor-util: sensor-util.o
- $(CC) $(CFLAGS) -lpal -lrt -lm -std=gnu99 -o $@ $^ $(LDFLAGS)
+ $(CC) $(CFLAGS) -lsdr -lpal -lrt -lm -std=gnu99 -o $@ $^ $(LDFLAGS)
.PHONY: clean
diff --git a/common/recipes-core/sensor-util/files/sensor-util.c b/common/recipes-core/sensor-util/files/sensor-util.c
index eb38d65..c37fc38 100644
--- a/common/recipes-core/sensor-util/files/sensor-util.c
+++ b/common/recipes-core/sensor-util/files/sensor-util.c
@@ -26,72 +26,74 @@
#include <stdint.h>
#include <string.h>
#include <errno.h>
+#include <stdbool.h>
#include <openbmc/pal.h>
+#include <openbmc/sdr.h>
static int
print_usage() {
- printf("Usage: sensor-util [ %s ] <sensor num>\n"
- "sensor num is optional.", pal_fru_list);
+ printf("Usage: sensor-util [ %s ] <--threshold> <sensor num>\n",
+ pal_fru_list);
}
static void
-print_single_sensor_reading(uint8_t fru, uint8_t *sensor_list, int sensor_cnt, uint8_t num) {
-
- int i;
- float fvalue;
- char name[24];
- char units[64];
- int ret = 0;
-
- for (i = 0; i < sensor_cnt; i++) {
-
- if (sensor_list[i] == num) {
- ret = 1;
- pal_get_sensor_name(fru, sensor_list[i], name);
- pal_get_sensor_units(fru, sensor_list[i], units);
-
- if (pal_sensor_read(fru, sensor_list[i], &fvalue) < 0) {
-
- printf("pal_sensor_read failed: fru: %d num: 0x%X name: %-23s\n",
- fru, sensor_list[i], name);
- } else {
- printf("%-23s: %.2f %s\n", name, fvalue, units);
- }
-
- break;
- }
+print_sensor_reading(float fvalue, thresh_sensor_t *thresh, bool threshold) {
+
+ if (threshold) {
+ printf("%-23s: Curr: %.2f %-8s\t"
+ " UCR: %.2f "
+ " UNC: %.2f "
+ " UNR: %.2f "
+ " LCR: %.2f "
+ " LNC: %.2f "
+ " LNR: %.2f \n",
+ thresh->name, fvalue, thresh->units,
+ thresh->ucr_thresh,
+ thresh->unc_thresh,
+ thresh->unr_thresh,
+ thresh->lcr_thresh,
+ thresh->lnc_thresh,
+ thresh->lnr_thresh);
+ } else {
+ printf("%-23s: %.2f %s\n", thresh->name, fvalue, thresh->units);
}
- if (!ret) {
- printf("Wrong sensor number!\n");
- print_usage();
- exit(-1);
- }
}
static void
-print_sensor_reading(uint8_t fru, uint8_t *sensor_list, int sensor_cnt) {
+calculate_sensor_reading(uint8_t fru, uint8_t *sensor_list, int sensor_cnt, int num, bool threshold) {
int i;
+ uint8_t snr_num;
float fvalue;
- char name[24];
- char units[64];
+ char path[64];
+ thresh_sensor_t thresh;
for (i = 0; i < sensor_cnt; i++) {
- /* Clear the variable */
- sprintf(name, "");
- sprintf(units, "");
+ snr_num = sensor_list[i];
- pal_get_sensor_name(fru, sensor_list[i], name);
- pal_get_sensor_units(fru, sensor_list[i], units);
+ /* If calculation is for a single sensor, ignore all others. */
+ if (num && snr_num != num) {
+ continue;
+ }
- if (pal_sensor_read(fru, sensor_list[i], &fvalue) < 0) {
+ if (threshold) {
+ if (sdr_get_snr_thresh(fru, snr_num, 0, &thresh))
+ syslog(LOG_ERR, "sdr_init_snr_thresh failed for FRU %d num: 0x%X", fru, snr_num);
+ } else {
+ sdr_get_sensor_name(fru, sensor_list[i], thresh.name);
+ sdr_get_sensor_units(fru, sensor_list[i], thresh.units);
+ }
- printf("pal_sensor_read failed: fru: %d num: 0x%X name: %-23s\n",
- fru, sensor_list[i], name);
+ usleep(50);
+
+ if (pal_sensor_read(fru, snr_num, &fvalue) < 0) {
+ printf("pal_sensor_read failed: FRU: %d num: 0x%X name: %-23s\n",
+ fru, sensor_list[i], thresh.name, thresh.units);
+ continue;
} else {
- printf("%-23s: %.2f %s\n", name, fvalue, units);
+ print_sensor_reading(fvalue, &thresh, threshold);
}
}
}
@@ -99,25 +101,32 @@ print_sensor_reading(uint8_t fru, uint8_t *sensor_list, int sensor_cnt) {
int
main(int argc, char **argv) {
+ int i;
int ret;
int sensor_cnt;
uint8_t *sensor_list;
uint8_t fru;
- uint8_t num;
+ uint8_t num = 0;
+ bool threshold = false;
- if (argc < 2 || argc > 3) {
+ if (argc < 2 || argc > 4) {
print_usage();
exit(-1);
}
- if (argc == 3) {
- errno = 0;
- num = (uint8_t) strtol(argv[2], NULL, 0);
- if (errno) {
- printf("Sensor number format incorrect.\n");
- print_usage();
- exit(-1);
+ i = 3; /* Starting at argument 3*/
+ while (argc > 2 && i <= argc) {
+ if (!(strcmp(argv[i-1], "--threshold"))) {
+ threshold = true;
+ } else {
+ errno = 0;
+ num = (uint8_t) strtol(argv[i-1], NULL, 0);
+ if (errno) {
+ print_usage();
+ exit(-1);
+ }
}
+ i++;
}
@@ -131,42 +140,24 @@ main(int argc, char **argv) {
fru = 1;
while (fru <= MAX_NUM_FRUS) {
- if (fru == FRU_NIC) {
- printf("\nsensor-util does not support nic\n");
- exit(-1);
- }
-
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
return ret;
}
- if (num) {
- print_single_sensor_reading(fru, sensor_list, sensor_cnt, num);
- } else {
- print_sensor_reading(fru, sensor_list, sensor_cnt);
- }
+ calculate_sensor_reading(fru, sensor_list, sensor_cnt, num, threshold);
fru++;
printf("\n");
}
} else {
- if (fru == FRU_NIC) {
- printf("\nsensor-util does not support nic\n");
- //exit(-1);
- }
-
ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
if (ret < 0) {
return ret;
}
- if (num) {
- print_single_sensor_reading(fru, sensor_list, sensor_cnt, num);
- } else {
- print_sensor_reading(fru, sensor_list, sensor_cnt);
- }
+ calculate_sensor_reading(fru, sensor_list, sensor_cnt, num, threshold);
}
return 0;
diff --git a/common/recipes-core/sensor-util/sensor-util_0.1.bb b/common/recipes-core/sensor-util/sensor-util_0.1.bb
index 227ec53..d802694 100644
--- a/common/recipes-core/sensor-util/sensor-util_0.1.bb
+++ b/common/recipes-core/sensor-util/sensor-util_0.1.bb
@@ -13,7 +13,7 @@ S = "${WORKDIR}"
binfiles = "sensor-util"
-DEPENDS =+ " libpal "
+DEPENDS =+ " libsdr libpal "
pkgdir = "sensor-util"
diff --git a/common/recipes-lib/fruid/files/fruid.c b/common/recipes-lib/fruid/files/fruid.c
index dc71ac8..e665c27 100644
--- a/common/recipes-lib/fruid/files/fruid.c
+++ b/common/recipes-lib/fruid/files/fruid.c
@@ -65,7 +65,9 @@ static char * calculate_time(uint8_t * mfg_time)
char * mfg_time_str = (char *) malloc(len);
if (!mfg_time_str) {
- syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "fruid: malloc: memory allocation failed\n");
+#endif
return NULL;
}
@@ -120,13 +122,17 @@ static char * get_chassis_type(uint8_t type_hex)
/* If the type is not in the list defined.*/
if (type > FRUID_CHASSIS_TYPECODE_MAX || type < FRUID_CHASSIS_TYPECODE_MIN) {
+#ifdef DEBUG
syslog(LOG_INFO, "fruid: chassis area: invalid chassis type\n");
+#endif
return NULL;
}
char * type_str = (char *) malloc(strlen(fruid_chassis_type[type]));
if (!type_str) {
- syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "fruid: malloc: memory allocation failed\n");
+#endif
return NULL;
}
@@ -179,7 +185,9 @@ static char * _fruid_area_field_read(uint8_t *offset)
field_len_eff > 0 ? (field = (char *) malloc(field_len_eff + 1)) :
(field = (char *) malloc(strlen(FIELD_EMPTY)));
if (!field) {
- syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "fruid: malloc: memory allocation failed\n");
+#endif
return NULL;
}
@@ -327,7 +335,9 @@ int parse_fruid_area_product(uint8_t * product,
/* Check if the format version is as per IPMI FRUID v1.0 format spec */
fruid_product->format_ver = product[index++];
if (fruid_product->format_ver != FRUID_FORMAT_VER) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: product_area: format version not supported");
+#endif
return EPROTONOSUPPORT;
}
@@ -339,7 +349,9 @@ int parse_fruid_area_product(uint8_t * product,
fruid_product->area_len, fruid_product->chksum);
if (ret) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: product_area: chksum not verified.");
+#endif
return EBADF;
}
@@ -401,7 +413,9 @@ int parse_fruid_area_board(uint8_t * board,
/* Check if the format version is as per IPMI FRUID v1.0 format spec */
fruid_board->format_ver = board[index++];
if (fruid_board->format_ver != FRUID_FORMAT_VER) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: board_area: format version not supported");
+#endif
return EPROTONOSUPPORT;
}
fruid_board->area_len = board[index++] * FRUID_AREA_LEN_MULTIPLIER;
@@ -412,7 +426,9 @@ int parse_fruid_area_board(uint8_t * board,
fruid_board->area_len, fruid_board->chksum);
if (ret) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: board_area: chksum not verified.");
+#endif
return EBADF;
}
@@ -471,7 +487,9 @@ int parse_fruid_area_chassis(uint8_t * chassis,
/* Check if the format version is as per IPMI FRUID v1.0 format spec */
fruid_chassis->format_ver = chassis[index++];
if (fruid_chassis->format_ver != FRUID_FORMAT_VER) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: chassis_area: format version not supported");
+#endif
return EPROTONOSUPPORT;
}
@@ -482,7 +500,9 @@ int parse_fruid_area_chassis(uint8_t * chassis,
ret = verify_chksum((uint8_t *) chassis,
fruid_chassis->area_len, fruid_chassis->chksum);
if (ret) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: chassis_area: chksum not verified.");
+#endif
return EBADF;
}
@@ -540,7 +560,9 @@ int parse_fruid_header(uint8_t * eeprom, fruid_header_t * header)
ret = verify_chksum((uint8_t *) header,
sizeof(fruid_header_t), header->chksum);
if (ret) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: common_header: chksum not verified.");
+#endif
return EBADF;
}
@@ -634,7 +656,9 @@ int fruid_parse(const char * bin, fruid_info_t * fruid)
/* Open the FRUID binary file */
fruid_fd = fopen(bin, "rb");
if (!fruid_fd) {
+#ifdef DEBUG
syslog(LOG_ERR, "fruid: unable to open the file");
+#endif
return ENOENT;
}
@@ -646,7 +670,9 @@ int fruid_parse(const char * bin, fruid_info_t * fruid)
eeprom = (uint8_t *) malloc(fruid_len);
if (!eeprom) {
- syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "fruid: malloc: memory allocation failed\n");
+#endif
return ENOMEM;
}
diff --git a/common/recipes-lib/ipmb/files/ipmb.c b/common/recipes-lib/ipmb/files/ipmb.c
index 731eeba..9fe12f5 100644
--- a/common/recipes-lib/ipmb/files/ipmb.c
+++ b/common/recipes-lib/ipmb/files/ipmb.c
@@ -42,26 +42,39 @@ lib_ipmb_handle(unsigned char bus_id,
int s, t, len;
struct sockaddr_un remote;
char sock_path[64] = {0};
+ struct timeval tv;
sprintf(sock_path, "%s_%d", SOCK_PATH_IPMB, bus_id);
// TODO: Need to update to reuse the socket instead of creating new
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- syslog(LOG_ALERT, "lib_ipmb_handle: socket() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "lib_ipmb_handle: socket() failed\n");
+#endif
return;
}
+ // setup timeout for receving on socket
+ tv.tv_sec = TIMEOUT_IPMB + 1;
+ tv.tv_usec = 0;
+
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
+
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, sock_path);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
- syslog(LOG_ALERT, "ipmb_handle: connect() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "ipmb_handle: connect() failed\n");
+#endif
goto clean_exit;
}
if (send(s, request, req_len, 0) == -1) {
- syslog(LOG_ALERT, "ipmb_handle: send() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "ipmb_handle: send() failed\n");
+#endif
goto clean_exit;
}
@@ -69,9 +82,13 @@ lib_ipmb_handle(unsigned char bus_id,
*res_len = t;
} else {
if (t < 0) {
- syslog(LOG_ALERT, "lib_ipmb_handle: recv() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "lib_ipmb_handle: recv() failed\n");
+#endif
} else {
- printf("Server closed connection\n");
+#ifdef DEBUG
+ syslog(LOG_DEBUG, "Server closed connection\n");
+#endif
}
}
diff --git a/common/recipes-lib/ipmb/files/ipmb.h b/common/recipes-lib/ipmb/files/ipmb.h
index d9bc16b..070e7ed 100644
--- a/common/recipes-lib/ipmb/files/ipmb.h
+++ b/common/recipes-lib/ipmb/files/ipmb.h
@@ -40,7 +40,10 @@ extern "C" {
// Slot#0 is on I2C Bus1
#define IPMB_BUS_SLOT0 1
-#define TIMEOUT_IPMI 4
+// TODO: Some IPMB responses take about 5-6 seconds
+// Need to add a timeout parameter to IPMB request
+// For now changing global timeout to 8 seconds
+#define TIMEOUT_IPMB 8
#define MAX_IPMB_RES_LEN 255
typedef struct _ipmb_req_t {
diff --git a/common/recipes-lib/ipmi/files/ipmi.c b/common/recipes-lib/ipmi/files/ipmi.c
index 3579eca..1b0f210 100644
--- a/common/recipes-lib/ipmi/files/ipmi.c
+++ b/common/recipes-lib/ipmi/files/ipmi.c
@@ -41,24 +41,37 @@ lib_ipmi_handle(unsigned char *request, unsigned char req_len,
int s, t, len;
struct sockaddr_un remote;
+ struct timeval tv;
// TODO: Need to update to reuse the socket instead of creating new
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- syslog(LOG_ALERT, "lib_ipmi_handle: socket() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "lib_ipmi_handle: socket() failed\n");
+#endif
return;
}
+ // setup timeout for receving on socket
+ tv.tv_sec = TIMEOUT_IPMI + 1;
+ tv.tv_usec = 0;
+
+ setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
+
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH_IPMI);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
- syslog(LOG_ALERT, "lib_ipmi_handle: connect() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "lib_ipmi_handle: connect() failed\n");
+#endif
return;
}
if (send(s, request, req_len, 0) == -1) {
- syslog(LOG_ALERT, "lib_ipmi_handle: send() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "lib_ipmi_handle: send() failed\n");
+#endif
return;
}
@@ -66,7 +79,9 @@ lib_ipmi_handle(unsigned char *request, unsigned char req_len,
*res_len = t;
} else {
if (t < 0) {
- syslog(LOG_ALERT, "lib_ipmi_handle: recv() failed\n");
+#ifdef DEBUG
+ syslog(LOG_WARNING, "lib_ipmi_handle: recv() failed\n");
+#endif
} else {
printf("Server closed connection");
}
diff --git a/common/recipes-lib/ipmi/files/ipmi.h b/common/recipes-lib/ipmi/files/ipmi.h
index 2ae7f1c..7b54dd1 100644
--- a/common/recipes-lib/ipmi/files/ipmi.h
+++ b/common/recipes-lib/ipmi/files/ipmi.h
@@ -36,6 +36,7 @@ extern "C" {
#define SIZE_AUTH_ENABLES 5
#define SIZE_IP_ADDR 4
+#define SIZE_IP6_ADDR 16
#define SIZE_MAC_ADDR 6
#define SIZE_NET_MASK 4
#define SIZE_IP_HDR 3
@@ -58,7 +59,8 @@ extern "C" {
#define SIZE_SEL_REC 16
-#define BIC_INTF_HDR_SIZE 3
+// NetFn, Command, Checksum, IANAID(3 bytes), BIC Interface type
+#define BIC_INTF_HDR_SIZE 7
#define LUN_OFFSET 2
@@ -76,6 +78,8 @@ extern "C" {
#define TYPE_ASCII_6BIT 2
#define TYPE_ASCII_8BIT 3
+#define TIMEOUT_IPMI 5
+
// IPMI request Structure (IPMI/Section 9.2)
typedef struct
{
@@ -231,6 +235,7 @@ typedef struct
unsigned char no_of_dest;
unsigned char dest_type[SIZE_DEST_TYPE];
unsigned char dest_addr[SIZE_DEST_ADDR];
+ unsigned char ip6_addr[SIZE_IP6_ADDR];
} lan_config_t;
// Structure to store Processor Information
@@ -322,6 +327,7 @@ enum
{
CMD_STORAGE_GET_FRUID_INFO = 0x10,
CMD_STORAGE_READ_FRUID_DATA = 0x11,
+ CMD_STORAGE_WRITE_FRUID_DATA = 0x12,
CMD_STORAGE_GET_SDR_INFO = 0x20,
CMD_STORAGE_RSV_SDR = 0x22,
CMD_STORAGE_GET_SDR = 0x23,
@@ -354,17 +360,21 @@ enum
CMD_OEM_SET_DIMM_INFO = 0x1C,
CMD_OEM_SET_POST_START = 0x73,
CMD_OEM_SET_POST_END = 0x74,
+ CMD_OEM_GET_SLOT_INFO = 0x7E,
};
// OEM 1S Command Codes (Quanta/FB defined commands)
enum
{
CMD_OEM_1S_MSG_IN = 0x1,
+ CMD_OEM_1S_MSG_OUT = 0x2,
CMD_OEM_1S_GET_GPIO = 0x3,
CMD_OEM_1S_GET_GPIO_CONFIG = 0x5,
CMD_OEM_1S_SET_GPIO_CONFIG = 0x6,
CMD_OEM_1S_INTR = 0x7,
CMD_OEM_1S_POST_BUF = 0x8,
+ CMD_OEM_1S_UPDATE_FW = 0x9,
+ CMD_OEM_1S_GET_FW_VER = 0xB,
CMD_OEM_1S_GET_CONFIG = 0xE,
CMD_OEM_1S_PLAT_DISC = 0xF,
CMD_OEM_1S_SET_CONFIG = 0x10,
@@ -408,6 +418,7 @@ enum
LAN_PARAM_NO_OF_DEST,
LAN_PARAM_DEST_TYPE,
LAN_PARAM_DEST_ADDR,
+ LAN_PARAM_IP6_ADDR = 197, /* OEM parameter for IPv6 */
};
// Boot Option Parameters (IPMI/Table 28-14)
@@ -441,6 +452,7 @@ enum
BIC_INTF_ME = 0x01,
BIC_INTF_SOL = 0x02,
BIC_INTF_KCS = 0x03,
+ BIC_INTF_KCS_SMM = 0x04,
};
void lib_ipmi_handle(unsigned char *request, unsigned char req_len,
diff --git a/common/recipes-lib/sdr/files/Makefile b/common/recipes-lib/sdr/files/Makefile
index 11fe3ee..607f914 100644
--- a/common/recipes-lib/sdr/files/Makefile
+++ b/common/recipes-lib/sdr/files/Makefile
@@ -3,7 +3,7 @@ lib: libsdr.so
libsdr.so: sdr.c
$(CC) $(CFLAGS) -fPIC -c -o sdr.o sdr.c
- $(CC) -lm -shared -o libsdr.so sdr.o -lc
+ $(CC) -lpal -lm -shared -o libsdr.so sdr.o -lc
.PHONY: clean
diff --git a/common/recipes-lib/sdr/files/sdr.c b/common/recipes-lib/sdr/files/sdr.c
index 208b10f..2b05bf5 100644
--- a/common/recipes-lib/sdr/files/sdr.c
+++ b/common/recipes-lib/sdr/files/sdr.c
@@ -27,6 +27,7 @@
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
+#include <string.h>
#include "sdr.h"
#define FIELD_RATE_UNIT(x) ((x & (0x07 << 3)) >> 3)
@@ -34,7 +35,9 @@
#define FIELD_PERCENTAGE(x) (x & 0x01)
#define FIELD_TYPE(x) ((x & (0x03 << 6)) >> 6)
-#define FIELD_LEN(x) (x & 0xF)
+#define FIELD_LEN(x) (x & 0x1F)
+
+#define MAX_NAME_LEN 16
/* Array for BCD Plus definition. */
const char bcd_plus_array[] = "0123456789 -.XXX";
@@ -48,10 +51,11 @@ const char * ascii_6bit[4] = {
};
/* Get the units of the sensor from the SDR */
-int
-sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
+static int
+_sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
char *units) {
+ int ret;
uint8_t percent;
uint8_t rate_idx;
uint8_t base_idx;
@@ -88,10 +92,46 @@ sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
return 0;
}
+int
+sdr_get_sensor_units(uint8_t fru, uint8_t snr_num, char *units) {
+
+ int ret = 0;
+ uint8_t op;
+ uint8_t modifier;
+ sdr_full_t *sdr;
+
+ sensor_info_t sinfo[MAX_SENSOR_NUM] = {0};
+
+ if (pal_sensor_sdr_init(fru, sinfo) < 0) {
+ sdr = NULL;
+ } else {
+ sdr = &sinfo[snr_num].sdr;
+ }
+
+ if (sdr != NULL) {
+ ret = _sdr_get_sensor_units(sdr, &op, &modifier, units);
+ if (ret < 0) {
+#ifdef DEBUG
+ syslog(LOG_ERR, "_sdr_get_sensor_units failed for FRU: %d snr_num: %d",
+ fru, snr_num);
+#endif
+ }
+ } else {
+ ret = pal_get_sensor_units(fru, snr_num, units);
+ if (ret < 0) {
+#ifdef DEBUG
+ syslog(LOG_ERR, "pal_get_sensor_units failed for FRU: %d snr_num: %d",
+ fru, snr_num);
+#endif
+ }
+ }
+
+ return ret;
+}
/* Get the name of the sensor from the SDR */
-int
-sdr_get_sensor_name(sdr_full_t *sdr, char *name) {
+static int
+_sdr_get_sensor_name(sdr_full_t *sdr, char *name) {
int field_type, field_len;
int idx, idx_eff, val;
char *str;
@@ -105,9 +145,9 @@ sdr_get_sensor_name(sdr_full_t *sdr, char *name) {
/* Case: length is zero */
if (field_len == 1) {
- syslog(LOG_ALERT, "get_sensor_name: str length is 0\n");
- // TODO: Fix this hack later
- sprintf(name, "%s", str);
+#ifdef DEBUG
+ syslog(LOG_WARNING, "get_sensor_name: str length is 0\n");
+#endif
return -1;
}
@@ -174,37 +214,326 @@ sdr_get_sensor_name(sdr_full_t *sdr, char *name) {
return 0;
}
-/* Populates all sensor_info_t struct using the path to SDR dump */
int
-sdr_init(char *path, sensor_info_t *sinfo) {
- int fd;
- uint8_t buf[MAX_SDR_LEN] = {0};
- uint8_t bytes_rd = 0;
- uint8_t snr_num = 0;
+sdr_get_sensor_name(uint8_t fru, uint8_t snr_num, char *name) {
+
+ int ret = 0;
sdr_full_t *sdr;
- while (access(path, F_OK) == -1) {
- sleep(5);
+ sensor_info_t sinfo[MAX_SENSOR_NUM] = {0};
+
+ if (pal_sensor_sdr_init(fru, sinfo) < 0) {
+ sdr = NULL;
+ } else {
+ sdr = &sinfo[snr_num].sdr;
}
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- syslog(LOG_ERR, "sdr_init: open failed for %s\n", path);
- return -1;
+ if (sdr != NULL) {
+ ret = _sdr_get_sensor_name(sdr, name);
+ if (ret < 0) {
+#ifdef DEBUG
+ syslog(LOG_ERR, "_sdr_get_sensor_name failed for FRU: %d snr_num: %d",
+ fru, snr_num);
+#endif
+ }
+ } else {
+ ret = pal_get_sensor_name(fru, snr_num, name);
+ if (ret < 0) {
+#ifdef DEBUG
+ syslog(LOG_ERR, "pal_get_sensor_name failed for FRU: %d snr_num: %d",
+ fru, snr_num);
+#endif
+ }
}
- while ((bytes_rd = read(fd, buf, sizeof(sdr_full_t))) > 0) {
- if (bytes_rd != sizeof(sdr_full_t)) {
- syslog(LOG_ERR, "sdr_init: read returns %d bytes\n", bytes_rd);
+ return ret;
+}
+
+/* Get the threshold values from the SDRs */
+static int
+get_sdr_thresh_val(uint8_t fru, sdr_full_t *sdr, uint8_t snr_num,
+ uint8_t thresh, void *value) {
+
+ int ret;
+ uint8_t x;
+ uint8_t m_lsb, m_msb, m;
+ uint8_t b_lsb, b_msb, b;
+ int8_t b_exp, r_exp;
+ uint8_t thresh_val;
+
+ switch (thresh) {
+ case UCR_THRESH:
+ thresh_val = sdr->uc_thresh;
+ break;
+ case UNC_THRESH:
+ thresh_val = sdr->unc_thresh;
+ break;
+ case UNR_THRESH:
+ thresh_val = sdr->unr_thresh;
+ break;
+ case LCR_THRESH:
+ thresh_val = sdr->lc_thresh;
+ break;
+ case LNC_THRESH:
+ thresh_val = sdr->lnc_thresh;
+ break;
+ case LNR_THRESH:
+ thresh_val = sdr->lnr_thresh;
+ break;
+ case POS_HYST:
+ thresh_val = sdr->pos_hyst;
+ break;
+ case NEG_HYST:
+ thresh_val = sdr->neg_hyst;
+ break;
+ default:
+#ifdef DEBUG
+ syslog(LOG_ERR, "get_sdr_thresh_val: reading unknown threshold val");
+#endif
return -1;
+ }
+
+ // y = (mx + b * 10^b_exp) * 10^r_exp
+ x = thresh_val;
+
+ m_lsb = sdr->m_val;
+ m_msb = sdr->m_tolerance >> 6;
+ m = (m_msb << 8) | m_lsb;
+
+ b_lsb = sdr->b_val;
+ b_msb = sdr->b_accuracy >> 6;
+ b = (b_msb << 8) | b_lsb;
+
+ // exponents are 2's complement 4-bit number
+ b_exp = sdr->rb_exp & 0xF;
+ if (b_exp > 7) {
+ b_exp = (~b_exp + 1) & 0xF;
+ b_exp = -b_exp;
+ }
+ r_exp = (sdr->rb_exp >> 4) & 0xF;
+ if (r_exp > 7) {
+ r_exp = (~r_exp + 1) & 0xF;
+ r_exp = -r_exp;
+ }
+
+ * (float *) value = ((m * x) + (b * pow(10, b_exp))) * (pow(10, r_exp));
+
+ return 0;
+}
+
+
+
+/*
+ * Populate all fields of thresh_sensor_t struct for a particular sensor.
+ * Incase the threshold value is 0 mask the check for that threshvold
+ * value in flag field.
+ */
+static int
+_sdr_get_snr_thresh(uint8_t fru, sdr_full_t *sdr, uint8_t snr_num,
+ uint8_t flag, thresh_sensor_t *snr) {
+
+ int ret;
+ int value;
+ float fvalue;
+ uint8_t op, modifier;
+
+ snr->flag = flag;
+ snr->curr_state = NORMAL_STATE;
+
+ if (_sdr_get_sensor_name(sdr, snr->name)) {
+#ifdef DEBUG
+ syslog(LOG_WARNING, "sdr_get_sensor_name: FRU %d: num: 0x%X: reading name"
+ " from SDR failed.", fru, snr_num);
+#endif
+ return -1;
+ }
+
+ // TODO: Add support for modifier (Mostly modifier is zero)
+ if (_sdr_get_sensor_units(sdr, &op, &modifier, snr->units)) {
+#ifdef DEBUG
+ syslog(LOG_WARNING, "sdr_get_sensor_units: FRU %d: num 0x%X: reading units"
+ " from SDR failed.", fru, snr_num);
+#endif
+ return -1;
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, UCR_THRESH, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UCR_THRESH",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->ucr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr->flag = CLEARBIT(snr->flag, UCR_THRESH);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, UNC_THRESH, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UNC_THRESH",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->unc_thresh = fvalue;
+ if (!(fvalue)) {
+ snr->flag = CLEARBIT(snr->flag, UNC_THRESH);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, UNR_THRESH, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UNR_THRESH",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->unr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr->flag = CLEARBIT(snr->flag, UNR_THRESH);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, LCR_THRESH, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LCR_THRESH",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->lcr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr->flag = CLEARBIT(snr->flag, LCR_THRESH);
}
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, LNC_THRESH, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LNC_THRESH",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->lnc_thresh = fvalue;
+ if (!(fvalue)) {
+ snr->flag = CLEARBIT(snr->flag, LNC_THRESH);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, LNR_THRESH, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LNR_THRESH",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->lnr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr->flag = CLEARBIT(snr->flag, LNR_THRESH);
+ }
+ }
- sdr = (sdr_full_t *) buf;
- snr_num = sdr->sensor_num;
- sinfo[snr_num].valid = true;
- memcpy(&sinfo[snr_num].sdr, sdr, sizeof(sdr_full_t));
+ if (get_sdr_thresh_val(fru, sdr, snr_num, POS_HYST, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, POS_HYST",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->pos_hyst = fvalue;
+ }
+
+ if (get_sdr_thresh_val(fru, sdr, snr_num, NEG_HYST, &fvalue)) {
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, NEG_HYST",
+ fru, snr_num, snr->name);
+#endif
+ } else {
+ snr->neg_hyst = fvalue;
}
return 0;
}
+int
+sdr_get_snr_thresh(uint8_t fru,uint8_t snr_num, uint8_t flag,
+ thresh_sensor_t *snr) {
+
+ int ret = 0;
+ sdr_full_t *sdr;
+#ifdef DEBUG
+ int cnt = 0;
+#endif /* DEBUG */
+ int retry = 0;
+
+ sensor_info_t sinfo[MAX_SENSOR_NUM] = {0};
+
+ ret = pal_sensor_sdr_init(fru, sinfo);
+
+ while (ret == ERR_NOT_READY) {
+
+ if (retry++ > MAX_RETRIES_SDR_INIT) {
+ syslog(LOG_INFO, "sdr_get_snr_thresh: failed for fru: %d", fru);
+ return -1;
+ }
+#ifdef DEBUG
+ syslog(LOG_INFO, "sdr_get_snr_thresh: fru: %d, ret: %d cnt: %d", fru, ret, cnt++);
+#endif /* DEBUG */
+ sleep(1);
+ ret = pal_sensor_sdr_init(fru, sinfo);
+ }
+
+
+ if (ret < 0) {
+ sdr = NULL;
+ } else {
+ sdr = &sinfo[snr_num].sdr;
+ }
+
+ if (sdr != NULL) {
+ ret = _sdr_get_snr_thresh(fru, sdr, snr_num, flag, snr);
+ if (ret < 0) {
+#ifdef DEBUG
+ syslog(LOG_ERR, "_sdr_get_snr_thresh failed for FRU: %d snr_num: %d",
+ fru, snr_num);
+#endif
+ }
+ } else {
+
+ snr->flag = flag;
+ ret = pal_get_sensor_name(fru, snr_num, snr->name);
+ ret = pal_get_sensor_units(fru, snr_num, snr->units);
+ ret = pal_get_sensor_threshold(fru, snr_num, UCR_THRESH, &(snr->ucr_thresh));
+ if (!(snr->ucr_thresh)) {
+ snr->flag = CLEARBIT(snr->flag, UCR_THRESH);
+ }
+ ret = pal_get_sensor_threshold(fru, snr_num, UNC_THRESH, &(snr->unc_thresh));
+ if (!(snr->unc_thresh)) {
+ snr->flag = CLEARBIT(snr->flag, UNC_THRESH);
+ }
+ ret = pal_get_sensor_threshold(fru, snr_num, UNR_THRESH, &(snr->unr_thresh));
+ if (!(snr->unr_thresh)) {
+ snr->flag = CLEARBIT(snr->flag, UNR_THRESH);
+ }
+ ret = pal_get_sensor_threshold(fru, snr_num, LCR_THRESH, &(snr->lcr_thresh));
+ if (!(snr->lcr_thresh)) {
+ snr->flag = CLEARBIT(snr->flag, LCR_THRESH);
+ }
+ ret = pal_get_sensor_threshold(fru, snr_num, LNC_THRESH, &(snr->lnc_thresh));
+ if (!(snr->lnc_thresh)) {
+ snr->flag = CLEARBIT(snr->flag, LNC_THRESH);
+ }
+ ret = pal_get_sensor_threshold(fru, snr_num, LNR_THRESH, &(snr->lnr_thresh));
+ if (!(snr->lnr_thresh)) {
+ snr->flag = CLEARBIT(snr->flag, LNR_THRESH);
+ }
+ ret = pal_get_sensor_threshold(fru, snr_num, POS_HYST, &(snr->pos_hyst));
+ ret = pal_get_sensor_threshold(fru, snr_num, NEG_HYST, &(snr->neg_hyst));
+
+ }
+
+ return ret;
+}
diff --git a/common/recipes-lib/sdr/files/sdr.h b/common/recipes-lib/sdr/files/sdr.h
index c474fb1..c260914 100644
--- a/common/recipes-lib/sdr/files/sdr.h
+++ b/common/recipes-lib/sdr/files/sdr.h
@@ -23,21 +23,40 @@
#include <stdbool.h>
#include <openbmc/ipmi.h>
+#include <openbmc/pal.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_SDR_LEN 64
-
+#define NORMAL_STATE 0x00
+#define MAX_SENSOR_NUM 0xFF
#define MAX_SENSOR_RATE_UNIT 7
#define MAX_SENSOR_BASE_UNIT 92
-typedef struct _sensor_info_t {
- bool valid;
- sdr_full_t sdr;
-} sensor_info_t;
+#define SETBIT(x, y) (x | (1 << y))
+#define GETBIT(x, y) ((x & (1 << y)) > y)
+#define CLEARBIT(x, y) (x & (~(1 << y)))
+#define GETMASK(y) (1 << y)
+
+/* To hold the sensor info and calculated threshold values from the SDR */
+typedef struct {
+ uint8_t flag;
+ float ucr_thresh;
+ float unc_thresh;
+ float unr_thresh;
+ float lcr_thresh;
+ float lnc_thresh;
+ float lnr_thresh;
+ float pos_hyst;
+ float neg_hyst;
+ int curr_state;
+ char name[17];
+ char units[64];
+
+} thresh_sensor_t;
/* List of all the Sensor Rate Units types. */
const char * sensor_rate_units[] = {
@@ -150,11 +169,10 @@ const char * sensor_base_units[] = {
"", /* 093 */
};
-int sdr_init(char *path, sensor_info_t *sinfo);
-
-int sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
- char *units);
-int sdr_get_sensor_name(sdr_full_t *sdr, char *name);
+int sdr_get_sensor_name(uint8_t fru, uint8_t snr_num, char *name);
+int sdr_get_sensor_units(uint8_t fru, uint8_t snr_num, char *units);
+int sdr_get_snr_thresh(uint8_t fru, uint8_t snr_num, uint8_t flag,
+ thresh_sensor_t *snr);
#ifdef __cplusplus
} // extern "C"
diff --git a/common/recipes-lib/sdr/libsdr_0.1.bb b/common/recipes-lib/sdr/libsdr_0.1.bb
index 958e0c6..73ebf3f 100644
--- a/common/recipes-lib/sdr/libsdr_0.1.bb
+++ b/common/recipes-lib/sdr/libsdr_0.1.bb
@@ -16,7 +16,7 @@ SRC_URI = "file://Makefile \
S = "${WORKDIR}"
-DEPENDS += " libipmi "
+DEPENDS += " libipmi libpal "
do_install() {
install -d ${D}${libdir}
diff --git a/common/recipes-rest/cherryPy/cherryPy_3.8.0.bb b/common/recipes-rest/cherryPy/cherryPy_3.8.0.bb
new file mode 100644
index 0000000..3c2179e
--- /dev/null
+++ b/common/recipes-rest/cherryPy/cherryPy_3.8.0.bb
@@ -0,0 +1,14 @@
+DESCRIPTION = "CherryPy HTTP framework"
+SECTION = "base"
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://cherrypy/LICENSE.txt;md5=a476d86a3f85c89411ecaad012eed1e3"
+
+SRC_URI = "https://pypi.python.org/packages/source/C/CherryPy/CherryPy-${PV}.tar.gz"
+SRC_URI[md5sum] = "542b96b2cd825e8120e8cd822bc18f4b"
+SRC_URI[sha256sum] = "ffcdb43667d4098247efaf8c82dd36d3dd4f8e5dc768ef5e90b480899e523bea"
+
+S = "${WORKDIR}/CherryPy-${PV}"
+
+inherit setuptools
+
+FILES_${PN} += "/usr/lib/* /usr/share/cherrypy"
diff --git a/common/recipes-rest/rest-api/files/node_server.py b/common/recipes-rest/rest-api/files/node_server.py
index 57a5c42..cf64f03 100644
--- a/common/recipes-rest/rest-api/files/node_server.py
+++ b/common/recipes-rest/rest-api/files/node_server.py
@@ -56,7 +56,7 @@ class serverNode(node):
else:
res = 'success'
- result = { "result": res }
+ result = { "result": res }
return result
@@ -64,6 +64,9 @@ def get_node_server(num):
actions = ["power-on",
"power-off",
"power-cycle",
- "graceful-shutdown"
+ "graceful-shutdown",
+ "12v-on",
+ "12v-off",
+ "12v-cycle"
]
return serverNode(num = num, actions = actions)
diff --git a/common/recipes-rest/rest-api/files/pal.py b/common/recipes-rest/rest-api/files/pal.py
index 8faef30..f0e076d 100644
--- a/common/recipes-rest/rest-api/files/pal.py
+++ b/common/recipes-rest/rest-api/files/pal.py
@@ -67,6 +67,14 @@ def pal_set_server_power(slot_id, command):
cmd.value = 2
elif command == 'graceful-shutdown':
cmd.value = 3
+ elif command == '12v-off':
+ cmd.value = 4
+ elif command == '12v-on':
+ cmd.value = 5
+ elif command == '12v-cycle':
+ cmd.value = 6
+ else:
+ return -1
ret = lpal_hndl.pal_set_server_power(slot_id, cmd)
if ret:
return -1
diff --git a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py
deleted file mode 100644
index 7c126d9..0000000
--- a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/python -tt
-# Copyright 2015-present Facebook. All rights reserved.
-#
-# This program file 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; version 2 of the License.
-#
-# 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 in a file named COPYING; if not, write to the
-# Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301 USA
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-from __future__ import unicode_literals
-
-from board_gpio_table import board_gpio_table
-from soc_gpio_table import soc_gpio_table
-
-import openbmc_gpio
-import openbmc_gpio_table
-
-import logging
-import sys
-
-
-def setup_board_gpio(soc_gpio_table, board_gpio_table, validate=True):
- soc = openbmc_gpio_table.SocGPIOTable(soc_gpio_table)
- gpio_configured = []
- for gpio in board_gpio_table:
- try:
- soc.config_function(gpio.gpio, write_through=False)
- gpio_configured.append(gpio.gpio)
- except openbmc_gpio_table.ConfigUnknownFunction as e:
- # not multiple-function GPIO pin
- pass
- except openbmc_gpio_table.NotSmartEnoughException as e:
- logging.error('Failed to configure "%s" for "%s": %s'
- % (gpio.gpio, gpio.shadow, str(e)))
-
- soc.write_to_hw()
-
- if validate:
- all_functions = set(soc.get_active_functions(refresh=True))
- for gpio in gpio_configured:
- if gpio not in all_functions:
- raise Exception('Failed to configure function "%s"' % gpio)
-
- for gpio in board_gpio_table:
- openbmc_gpio.gpio_export(gpio.gpio, gpio.shadow)
- if gpio.value == openbmc_gpio_table.GPIO_INPUT:
- continue
- elif gpio.value == openbmc_gpio_table.GPIO_OUT_HIGH:
- openbmc_gpio.gpio_set(gpio.gpio, 1)
- elif gpio.value == openbmc_gpio_table.GPIO_OUT_LOW:
- openbmc_gpio.gpio_set(gpio.gpio, 0)
- else:
- raise Exception('Invalid value "%s"' % gpio.value)
-
-def main():
- print('Setting up GPIOs ... ', end='')
- sys.stdout.flush()
- openbmc_gpio.setup_shadow()
- setup_board_gpio(soc_gpio_table, board_gpio_table)
- print('Done')
- sys.stdout.flush()
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py
index dda8a98..d188dcb 100644
--- a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py
+++ b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py
@@ -21,6 +21,7 @@ from __future__ import unicode_literals
from soc_gpio import soc_get_register
+import openbmc_gpio
import logging
import os
import sys
@@ -267,3 +268,36 @@ class BoardGPIO(object):
self.gpio = gpio
self.shadow = shadow
self.value = value
+
+def setup_board_gpio(soc_gpio_table, board_gpio_table, validate=True):
+ soc = SocGPIOTable(soc_gpio_table)
+ gpio_configured = []
+ for gpio in board_gpio_table:
+ try:
+ soc.config_function(gpio.gpio, write_through=False)
+ gpio_configured.append(gpio.gpio)
+ except ConfigUnknownFunction as e:
+ # not multiple-function GPIO pin
+ pass
+ except NotSmartEnoughException as e:
+ logging.error('Failed to configure "%s" for "%s": %s'
+ % (gpio.gpio, gpio.shadow, str(e)))
+
+ soc.write_to_hw()
+
+ if validate:
+ all_functions = set(soc.get_active_functions(refresh=True))
+ for gpio in gpio_configured:
+ if gpio not in all_functions:
+ raise Exception('Failed to configure function "%s"' % gpio)
+
+ for gpio in board_gpio_table:
+ openbmc_gpio.gpio_export(gpio.gpio, gpio.shadow)
+ if gpio.value == GPIO_INPUT:
+ continue
+ elif gpio.value == GPIO_OUT_HIGH:
+ openbmc_gpio.gpio_set(gpio.gpio, 1)
+ elif gpio.value == GPIO_OUT_LOW:
+ openbmc_gpio.gpio_set(gpio.gpio, 0)
+ else:
+ raise Exception('Invalid value "%s"' % gpio.value)
diff --git a/common/recipes-utils/openbmc-gpio/files/setup.py b/common/recipes-utils/openbmc-gpio/files/setup.py
index 59c7de4..bf7be3d 100644
--- a/common/recipes-utils/openbmc-gpio/files/setup.py
+++ b/common/recipes-utils/openbmc-gpio/files/setup.py
@@ -18,6 +18,7 @@
from distutils.core import setup
+from setup_board import board_py_modules
setup(
name = 'openbmc-gpio',
@@ -31,6 +32,6 @@ setup(
'phymemory',
'soc_gpio',
'soc_gpio_table',
- 'board_gpio_table',
- ],
+ 'board_gpio_table', ]
+ + board_py_modules ,
)
diff --git a/common/recipes-utils/openbmc-gpio/files/setup_board.py b/common/recipes-utils/openbmc-gpio/files/setup_board.py
new file mode 100644
index 0000000..aff7398
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/setup_board.py
@@ -0,0 +1,23 @@
+# Copyright 2015-present Facebook. All rights reserved.
+#
+# This program file 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; version 2 of the License.
+#
+# 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 in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+# This is a dummy board GPIO table. If this is included in the final image,
+# please double check the configuration of your image to define the correct
+# GPIO table to be used for your board.
+
+board_py_modules = [
+]
diff --git a/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb b/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb
index 6bf4cc1..a2b46d4 100644
--- a/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb
+++ b/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb
@@ -25,12 +25,12 @@ SRC_URI = " \
file://board_gpio_table.py \
file://openbmc_gpio.py \
file://openbmc_gpio_table.py \
- file://openbmc_gpio_setup.py \
file://openbmc_gpio_util.py \
file://phymemory.py \
file://setup.py \
file://soc_gpio.py \
file://soc_gpio_table.py \
+ file://setup_board.py \
"
S = "${WORKDIR}"
@@ -41,9 +41,6 @@ OPENBMC_GPIO_UTILS = " \
OPENBMC_GPIO_SOC_TABLE = "soc_gpio_table.py"
-# Change OPENBMC_GPIO_SETUP to "0" to exclude openbmc_gpio_setup.py from the image
-OPENBMC_GPIO_SETUP = "1"
-
inherit distutils
DEPENDS_${PN} = "python python-distribute update-rc.d-native"
@@ -63,13 +60,5 @@ do_install_append() {
for f in ${OPENBMC_GPIO_UTILS}; do
install -m 755 $f ${localbindir}/${f}
done
-
- install -d ${D}${sysconfdir}/init.d
- install -d ${D}${sysconfdir}/rcS.d
- if [ "${OPENBMC_GPIO_SETUP}" == "1" ]; then
- install -m 755 openbmc_gpio_setup.py ${D}${sysconfdir}/init.d/openbmc_gpio_setup.py
- update-rc.d -r ${D} openbmc_gpio_setup.py start 59 S .
- fi
}
-FILES_${PN} += "/usr/local/bin ${sysconfdir}"
diff --git a/common/recipes-utils/spatula/files/setup-spatula.sh b/common/recipes-utils/spatula/files/setup-spatula.sh
index 391a212..238f395 100644
--- a/common/recipes-utils/spatula/files/setup-spatula.sh
+++ b/common/recipes-utils/spatula/files/setup-spatula.sh
@@ -31,7 +31,7 @@
. /etc/init.d/functions
ACTION="$1"
-CMD="/usr/local/bin/spatula_wrapper.py"
+CMD="/usr/local/bin/spatula_wrapper.py --lldp"
case "$ACTION" in
start)
echo -n "Setting up Spatula: "
diff --git a/common/recipes-utils/spatula/files/spatula_wrapper.py b/common/recipes-utils/spatula/files/spatula_wrapper.py
index 2717bef..770e4e8 100644
--- a/common/recipes-utils/spatula/files/spatula_wrapper.py
+++ b/common/recipes-utils/spatula/files/spatula_wrapper.py
@@ -24,35 +24,81 @@ import os
import subprocess
import time
import argparse
+import re
SPATULA_FILE = '/etc/spatula/spatula'
+LLDP_UTIL = '/usr/bin/lldp-util'
LOG_FORMAT = '[%(levelname)s] %(asctime)s: %(message)s'
DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
DEFAULT_SLEEP = 900 # default sleep 15 mins
+DEFAULT_PORT = 8087
+DEFAULT_INTERFACE = 'usb0'
class SpatulaWrapper(object):
def __init__(self, address='fe80::2', interface='usb0',
- port=8087, ssl=False):
- proto = 'http'
- if ssl:
- proto = 'https'
+ port=8087, tls=False, lldp=False):
+ self.interface = interface
+ self.lldp = lldp
+ self.port = port
+ self.proto = 'http'
+ if tls:
+ self.proto = 'https'
+ # not used if auto-discovering
self.url = '{proto}://{address}%{iface}:{port}'.format(
- proto = proto,
+ proto = self.proto,
address = address,
- iface = interface,
- port = port)
+ iface = self.interface,
+ port = self.port)
+
+ def _getLldpMessage(self):
+ try:
+ if os.path.exists(LLDP_UTIL):
+ # request a single packet and time out in 30 seconds
+ lldp = subprocess.Popen([LLDP_UTIL, '-n', '4', '-t', '30'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ found = []
+ for line in lldp.stdout:
+ # example (one line):
+ # LLDP: local_port=eth0 \
+ # remote_system=rsw1bz.19.snc1.facebook.com \
+ # remote_port=00:90:fb:52:1a:49
+ if line.startswith('LLDP: '):
+ matches = re.findall(r'\w+=\S+', line.replace('LLDP: ', ''))
+ matches = [m.split('=', 1) for m in matches]
+ found.append(dict(matches))
+ if not found:
+ raise Exception('timed out waiting for LLDP packet')
+ # dedupe before returning since we may get multiple packets
+ # from the same device
+ return [dict(t) for t in set([tuple(d.items()) for d in found])]
+ else:
+ raise Exception('missing lldp-util: {}'.format(LLDP_UTIL))
+ except Exception as err:
+ raise Exception('failed discovering management system via LLDP: {}'.format(err))
def _getSpatula(self, endpoint='/spatula'):
'''
Get the executable spatula script from the host.
'''
- url = '{}{}'.format(self.url, endpoint)
- try:
- request = urllib2.Request(url)
- response = urllib2.urlopen(request)
- return response.read()
- except Exception as err:
- raise Exception('failed getting Spatula {}: {}'.format(url, err))
+ urls = []
+ urls.append('{}{}'.format(self.url, endpoint))
+ if self.lldp:
+ for lldp in self._getLldpMessage():
+ urls.append('{proto}://{address}%{iface}:{port}{endpoint}'.format(
+ proto = self.proto,
+ address = lldp['remote_system'],
+ iface = lldp['local_port'],
+ port = self.port,
+ endpoint = endpoint))
+ for url in urls:
+ try:
+ request = urllib2.Request(url)
+ response = urllib2.urlopen(request)
+ return response.read()
+ except Exception as err:
+ continue
+ raise Exception('failed getting Spatula {}: {}'.format(urls, err))
def _success(self, endpoint='/success'):
'''
@@ -114,7 +160,18 @@ if __name__ == '__main__':
args = argparse.ArgumentParser()
args.add_argument('-s', '--sleep', default=DEFAULT_SLEEP,
help='Sleep time between spatula runs (default=%(default)s)')
+ args.add_argument('--interface', '-i', default=DEFAULT_INTERFACE,
+ help='Interface to use for management system')
+ args.add_argument('--port', '-p', default=DEFAULT_PORT,
+ help='Port to contact on management system')
+ args.add_argument('--lldp', default=False, action="store_true",
+ help='Automatically discover management system with LLDP')
+ args.add_argument('--tls', default=False, action="store_true",
+ help='Connect to bmc_proxy using TLS')
params = args.parse_args()
logging.basicConfig(format=LOG_FORMAT, datefmt=DATE_FORMAT)
- wrapper = SpatulaWrapper()
+ wrapper = SpatulaWrapper(interface=params.interface,
+ tls=params.tls,
+ port=params.port,
+ lldp=params.lldp)
wrapper.run(params.sleep)
OpenPOWER on IntegriCloud