summaryrefslogtreecommitdiffstats
path: root/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp')
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp390
1 files changed, 297 insertions, 93 deletions
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
OpenPOWER on IntegriCloud