102
102
#define FAN_DIR_FAULT 0
103
103
#define FAN_DIR_B2F 1
104
104
#define FAN_DIR_F2B 2
105
- #define THERMAL_DIR_F2B_STR "R1241-F0001 "
106
- #define THERMAL_DIR_B2F_STR "R1241-F0002 "
107
- #define FAN_DIR_F2B_STR "R1241-F9001 "
105
+ #define THERMAL_DIR_F2B_STR "R1241-F9019-01 "
106
+ #define THERMAL_DIR_B2F_STR "Undefined "
107
+ #define FAN_DIR_F2B_STR "R1241-FN019-013JW "
108
108
#define FAN_DIR_B2F_STR "R1241-F9002"
109
109
#define DELTA_PSU_DIR_F2B_STR "DPS-1100FB"
110
110
#define DELTA_PSU_DIR_B2F_STR "DPS-1100AB"
@@ -140,7 +140,7 @@ static int calculate_fan_one_fail_pwm(int cur_temp, int last_temp);
140
140
141
141
static int read_temp_sysfs (struct sensor_info_sysfs * sensor );
142
142
static int read_temp_directly_sysfs (struct sensor_info_sysfs * sensor );
143
-
143
+ static void get_direction_str ( int direction , char * message );
144
144
145
145
struct line_policy fishbone48_f2b_normal = {
146
146
.temp_hyst = CRITICAL_TEMP_HYST ,
@@ -631,6 +631,7 @@ static struct thermal_policy b2f_one_fail_policy = {
631
631
.line = & fishbone48_b2f_onefail ,
632
632
};
633
633
634
+ /* Global variables */
634
635
static struct thermal_policy * policy = NULL ;
635
636
static int pid_using = 0 ;
636
637
static int direction = FAN_DIR_INIT ;
@@ -1211,7 +1212,7 @@ static int alarm_temp_update(int *alarm)
1211
1212
info -> flag &= ~HIGH_MAX_BIT ;
1212
1213
syslog (LOG_INFO , "%s is NORMAL, set fan normal speed" , info -> name );
1213
1214
}
1214
- #ifdef DEBU
1215
+ #ifdef DEBUG
1215
1216
syslog (LOG_DEBUG , "[xuth] Major max bit: %d, recovery count: %d" , * alarm & HIGH_MAX_BIT ? 1 : 0 , info -> recovery_count );
1216
1217
#endif
1217
1218
}
@@ -1961,6 +1962,17 @@ char* find_sub_string(char *src, const char *sub, int src_len)
1961
1962
return NULL ;
1962
1963
}
1963
1964
1965
+ /*
1966
+ * Determine the system's thermal direction from the fan EEPROMs.
1967
+ * If the fans are not all in the same direction, thermal direction will
1968
+ * determine by the large majority. If the total number of fan directions
1969
+ * are even, assume F2B.
1970
+ *
1971
+ * This also updates fans status and info in global variable fantray_info[].
1972
+ *
1973
+ * @param direction System thermal direction.
1974
+ * @return fan direction one of FAN_DIR_F2B or FAN_DIR_B2F.
1975
+ */
1964
1976
static int get_fan_direction (int direction )
1965
1977
{
1966
1978
struct fantray_info_stu_sysfs * fantray ;
@@ -1972,6 +1984,9 @@ static int get_fan_direction(int direction)
1972
1984
int i = 0 ;
1973
1985
char * pn ;
1974
1986
int ret ;
1987
+ char direction_str [8 ];
1988
+
1989
+ get_direction_str (direction , direction_str );
1975
1990
1976
1991
for (; i < TOTAL_FANS + TOTAL_PSUS ; i ++ )
1977
1992
{
@@ -2007,9 +2022,9 @@ static int get_fan_direction(int direction)
2007
2022
}
2008
2023
fantray -> direction = FAN_DIR_F2B ;
2009
2024
if (direction != fantray -> direction )
2010
- syslog (LOG_ERR , "%s airflow direction mismatch, direction is F2B, system direction is B2F " , fantray -> name );
2025
+ syslog (LOG_ERR , "%s airflow direction mismatch, direction is F2B, system direction is %s " , fantray -> name , direction_str );
2011
2026
else
2012
- syslog (LOG_WARNING , "%s airflow direction match, direction is F2B, system direction is F2B " , fantray -> name );
2027
+ syslog (LOG_WARNING , "%s airflow direction match, direction is F2B, system direction is %s " , fantray -> name , direction_str );
2013
2028
} else if (find_sub_string (buffer , FAN_DIR_B2F_STR , sizeof (buffer ))) {
2014
2029
r2f_fan_cnt ++ ;
2015
2030
if (fantray -> direction == FAN_DIR_FAULT ) {
@@ -2021,9 +2036,9 @@ static int get_fan_direction(int direction)
2021
2036
}
2022
2037
fantray -> direction = FAN_DIR_B2F ;
2023
2038
if (direction != fantray -> direction )
2024
- syslog (LOG_ERR , "%s airflow direction mismatch, direction is B2F, system direction is F2B " , fantray -> name );
2039
+ syslog (LOG_ERR , "%s airflow direction mismatch, direction is B2F, system direction is %s " , fantray -> name , direction_str );
2025
2040
else
2026
- syslog (LOG_WARNING , "%s airflow direction match, direction is B2F, system direction is B2F " , fantray -> name );
2041
+ syslog (LOG_WARNING , "%s airflow direction match, direction is B2F, system direction is %s " , fantray -> name , direction_str );
2027
2042
} else {
2028
2043
fantray -> direction = FAN_DIR_FAULT ;
2029
2044
if (ret > 0 ) {
@@ -2044,9 +2059,9 @@ static int get_fan_direction(int direction)
2044
2059
}
2045
2060
fantray -> direction = FAN_DIR_F2B ;
2046
2061
if (direction != fantray -> direction )
2047
- syslog (LOG_ERR , "%s airflow direction mismatch, direction is F2B, system direction is B2F " , fantray -> name );
2062
+ syslog (LOG_ERR , "%s airflow direction mismatch, direction is F2B, system direction is %s " , fantray -> name , direction_str );
2048
2063
else
2049
- syslog (LOG_WARNING , "%s airflow direction match, direction is F2B, system direction is F2B " , fantray -> name );
2064
+ syslog (LOG_WARNING , "%s airflow direction match, direction is F2B, system direction is %s " , fantray -> name , direction_str );
2050
2065
} else if (find_sub_string (buffer , DELTA_PSU_DIR_B2F_STR , sizeof (buffer ))) {
2051
2066
if (fantray -> direction == FAN_DIR_FAULT ) {
2052
2067
syslog (LOG_WARNING , "%s eeprom is NORMAL" , fantray -> name );
@@ -2057,9 +2072,9 @@ static int get_fan_direction(int direction)
2057
2072
}
2058
2073
fantray -> direction = FAN_DIR_B2F ;
2059
2074
if (direction != fantray -> direction )
2060
- syslog (LOG_ERR , "%s airflow direction mismatch, direction is B2F, system direction is F2B " , fantray -> name );
2075
+ syslog (LOG_ERR , "%s airflow direction mismatch, direction is B2F, system direction is %s " , fantray -> name , direction_str );
2061
2076
else
2062
- syslog (LOG_WARNING , "%s airflow direction match, direction is B2F, system direction is B2F " , fantray -> name );
2077
+ syslog (LOG_WARNING , "%s airflow direction match, direction is B2F, system direction is %s " , fantray -> name , direction_str );
2063
2078
} else if (find_sub_string (buffer , ACBEL_PSU_DIR_F2B_STR , sizeof (buffer ))) {
2064
2079
if (fantray -> direction == FAN_DIR_FAULT ) {
2065
2080
syslog (LOG_WARNING , "%s eeprom is NORMAL" , fantray -> name );
@@ -2070,9 +2085,9 @@ static int get_fan_direction(int direction)
2070
2085
}
2071
2086
fantray -> direction = FAN_DIR_F2B ;
2072
2087
if (direction != fantray -> direction )
2073
- syslog (LOG_ERR , "%s airflow direction mismatch, direction is F2B, system direction is B2F " , fantray -> name );
2088
+ syslog (LOG_ERR , "%s airflow direction mismatch, direction is F2B, system direction is %s " , fantray -> name , direction_str );
2074
2089
else
2075
- syslog (LOG_WARNING , "%s airflow direction match, direction is F2B, system direction is F2B " , fantray -> name );
2090
+ syslog (LOG_WARNING , "%s airflow direction match, direction is F2B, system direction is %s " , fantray -> name , direction_str );
2076
2091
} else if (find_sub_string (buffer , ACBEL_PSU_DIR_B2F_STR , sizeof (buffer ))) {
2077
2092
if (fantray -> direction == FAN_DIR_FAULT ) {
2078
2093
syslog (LOG_WARNING , "%s eeprom is NORMAL" , fantray -> name );
@@ -2083,9 +2098,9 @@ static int get_fan_direction(int direction)
2083
2098
}
2084
2099
fantray -> direction = FAN_DIR_B2F ;
2085
2100
if (direction != fantray -> direction )
2086
- syslog (LOG_ERR , "%s airflow direction mismatch, direction is B2F, system direction is F2B " , fantray -> name );
2101
+ syslog (LOG_ERR , "%s airflow direction mismatch, direction is B2F, system direction is %s " , fantray -> name , direction_str );
2087
2102
else
2088
- syslog (LOG_WARNING , "%s airflow direction match, direction is B2F, system direction is B2F " , fantray -> name );
2103
+ syslog (LOG_WARNING , "%s airflow direction match, direction is B2F, system direction is %s " , fantray -> name , direction_str );
2089
2104
} else {
2090
2105
fantray -> direction = FAN_DIR_FAULT ;
2091
2106
if (ret > 0 ) {
@@ -2106,6 +2121,13 @@ static int get_fan_direction(int direction)
2106
2121
}
2107
2122
}
2108
2123
2124
+ /*
2125
+ * Get system thermal direction from TLV EEPROM.
2126
+ * If falis to read thermal direction, then set the fan speed to maximum.
2127
+ *
2128
+ * @return the systen thermal direction FAN_DIR_F2B or FAN_DIR_B2F or less than
2129
+ * zero if cannot determine the system thermal direction.
2130
+ */
2109
2131
int get_thermal_direction (void )
2110
2132
{
2111
2133
char buffer [128 ];
@@ -2114,43 +2136,74 @@ int get_thermal_direction(void)
2114
2136
memset (command , 0 , sizeof (command ));
2115
2137
sprintf (command , "/usr/bin/decode-syseeprom | grep 'Part Number' 2> /dev/null" );
2116
2138
fp = popen (command , "r" );
2117
- int thermal_dir ;
2139
+ int thermal_dir = FAN_DIR_INIT ;
2118
2140
int fan , fan_speed ;
2119
2141
2142
+ /* We have 2 possible errors here
2143
+ * 1: The eeprom canot be read
2144
+ * 2: The PN does not match any expected cases
2145
+ * Both will comes to the conclusion that we cannot know the system
2146
+ * thermal direction here.
2147
+ *
2148
+ * We can do either let the fan be 100% and STOP PID control OR
2149
+ * determine the fan speed from the fans and let running.
2150
+ * But this might cause the program continue running with incorrect
2151
+ * thermal parameter.
2152
+ *
2153
+ * I perfer to go with 100% and exit. The service can be started again,
2154
+ * after the issue is fixed.
2155
+ */
2156
+
2120
2157
if (!fp ) {
2121
- syslog (LOG_ERR , "failed to get thermal direction" );
2122
- syslog (LOG_WARNING , "thermal direction judged by fan direction" );
2158
+ syslog (LOG_ERR , "failed to read thermal direction from TLV EEPROM, FAN speed is set to 100%%" );
2159
+ fan_speed = FAN_MAX ;
2160
+ for (fan = 0 ; fan < TOTAL_FANS ; fan ++ ) {
2161
+ write_fan_speed (fan , fan_speed );
2162
+ }
2163
+ write_psu_fan_speed (fan , fan_speed );
2123
2164
} else {
2124
2165
char temp ;
2125
2166
int len = 0 ;
2126
2167
memset (buffer , 0 , sizeof (buffer ));
2127
2168
fread (buffer , sizeof (char ), sizeof (buffer ), fp );
2128
2169
pclose (fp );
2129
2170
if (find_sub_string (buffer , THERMAL_DIR_F2B_STR , sizeof (buffer ))) {
2130
- syslog (LOG_INFO , "system direction is F2B" );
2171
+ syslog (LOG_INFO , "system thermal direction is F2B" );
2131
2172
thermal_dir = FAN_DIR_F2B ;
2132
2173
} else if (find_sub_string (buffer , THERMAL_DIR_B2F_STR , sizeof (buffer ))) {
2133
- syslog (LOG_INFO , "system direction is B2F" );
2174
+ syslog (LOG_INFO , "system thermal direction is B2F" );
2134
2175
thermal_dir = FAN_DIR_B2F ;
2135
2176
} else {
2136
- syslog (LOG_ERR , "system direction is unknown, FAN speed is set to 100%%" );
2177
+ syslog (LOG_ERR , "unrecognized system P/N in TLV EEPROM\n" );
2178
+ syslog (LOG_ERR , "system thermal direction is unknown, FAN speed is set to 100%%" );
2137
2179
fan_speed = FAN_MAX ;
2138
2180
for (fan = 0 ; fan < TOTAL_FANS ; fan ++ ) {
2139
2181
write_fan_speed (fan , fan_speed );
2140
2182
}
2141
2183
write_psu_fan_speed (fan , fan_speed );
2142
2184
}
2143
2185
}
2186
+
2144
2187
get_fan_direction (thermal_dir );
2145
2188
2146
2189
return thermal_dir ;
2147
2190
}
2148
2191
2149
- static void update_thermal_direction ()
2192
+ static int update_thermal_direction ()
2150
2193
{
2151
2194
struct fantray_info_stu_sysfs * fantray ;
2152
2195
int dir = get_thermal_direction ();
2196
+
2197
+ /* Just pop out with error code, if error happen */
2198
+ if (dir < 0 )
2199
+ return dir ;
2200
+
2153
2201
if (direction != dir ) {
2202
+ /*
2203
+ * This line only called once. Even the function name is update.
2204
+ * If the thermal direction is not set, the whole program will
2205
+ * runs into unexpected behaviors.
2206
+ */
2154
2207
direction = dir ;
2155
2208
if (direction == FAN_DIR_F2B ) {
2156
2209
syslog (LOG_INFO , "setting F2B thermal policy" );
@@ -2161,6 +2214,7 @@ static void update_thermal_direction()
2161
2214
policy = & b2f_normal_policy ;
2162
2215
}
2163
2216
}
2217
+ return 0 ;
2164
2218
}
2165
2219
2166
2220
static int pid_ini_parser (struct board_info_stu_sysfs * info , FILE * fp )
@@ -2263,8 +2317,16 @@ static int load_pid_config(void)
2263
2317
static int policy_init (void )
2264
2318
{
2265
2319
int slope ;
2320
+ int ret ;
2266
2321
syslog (LOG_NOTICE , "Initializing FSC policy" );
2267
- update_thermal_direction ();
2322
+
2323
+ ret = update_thermal_direction ();
2324
+
2325
+ if (ret < 0 ){
2326
+ syslog (LOG_NOTICE , "Failed, Unknown thermal direction" );
2327
+ syslog (LOG_NOTICE , "Trying to exit..." );
2328
+ return ret ;
2329
+ }
2268
2330
2269
2331
load_pid_config ();
2270
2332
if (pid_using == 0 ) {
@@ -2288,7 +2350,18 @@ static int policy_init(void)
2288
2350
return 0 ;
2289
2351
}
2290
2352
2353
+ static void get_direction_str (int direction , char * message )
2354
+ {
2355
+ const char * airflow_strings [] = { "Unknown" ,
2356
+ "Fault" ,
2357
+ "B2F" ,
2358
+ "F2B" };
2359
+
2360
+ strcpy ( message , airflow_strings [ direction + 1 ] );
2361
+ }
2362
+
2291
2363
int main (int argc , char * * argv ) {
2364
+ int ret ;
2292
2365
int critical_temp ;
2293
2366
int old_temp = -1 ;
2294
2367
struct fantray_info_stu_sysfs * info ;
@@ -2324,7 +2397,11 @@ int main(int argc, char **argv) {
2324
2397
daemon (1 , 0 );
2325
2398
syslog (LOG_DEBUG , "Starting up; system should have %d fans." , TOTAL_FANS );
2326
2399
fancpld_watchdog_enable ();
2327
- policy_init ();
2400
+ ret = policy_init ();
2401
+ if (ret < 0 ){
2402
+ syslog (LOG_NOTICE , "exit" );
2403
+ return ret ;
2404
+ }
2328
2405
sleep (5 ); /* Give the fans time to come up to speed */
2329
2406
while (1 ) {
2330
2407
fan_speed_temp = 0 ;
0 commit comments