diff options
Diffstat (limited to 'common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp')
-rw-r--r-- | common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp | 390 |
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 |