| 129 | | static void print_temp_limits(double limit1, double limit2, |
| 130 | | const char *name1, const char *name2, int alarm) |
| 131 | | { |
| 132 | | if (fahrenheit) { |
| 133 | | limit1 = deg_ctof(limit1); |
| 134 | | limit2 = deg_ctof(limit2); |
| 135 | | } |
| 136 | | |
| 137 | | if (name2) { |
| 138 | | printf("(%-4s = %+5.1f%s, %-4s = %+5.1f%s) ", |
| 139 | | name1, limit1, degstr, |
| 140 | | name2, limit2, degstr); |
| 141 | | } else if (name1) { |
| 142 | | printf("(%-4s = %+5.1f%s) ", |
| 143 | | name1, limit1, degstr); |
| 144 | | } else { |
| 145 | | printf(" "); |
| 146 | | } |
| 147 | | |
| 148 | | if (alarm) |
| 149 | | printf("ALARM "); |
| 150 | | } |
| | 131 | static void print_alarms(struct sensor_subfeature_data *alarms, int alarm_count, |
| | 132 | int leading_spaces) |
| | 133 | { |
| | 134 | int i, printed; |
| | 135 | |
| | 136 | printf("%*s", leading_spaces + 7, "ALARM"); |
| | 137 | if (alarm_count > 1 || alarms[0].name) { |
| | 138 | printf(" ("); |
| | 139 | for (i = printed = 0; i < alarm_count; i++) { |
| | 140 | if (alarms[i].name) { |
| | 141 | if (printed) |
| | 142 | printf(", "); |
| | 143 | printf("%s", alarms[i].name); |
| | 144 | printed = 1; |
| | 145 | } |
| | 146 | } |
| | 147 | printf(")"); |
| | 148 | } |
| | 149 | } |
| | 150 | |
| | 151 | static void print_limits(struct sensor_subfeature_data *limits, |
| | 152 | int limit_count, |
| | 153 | struct sensor_subfeature_data *alarms, |
| | 154 | int alarm_count, int label_size, |
| | 155 | const char *fmt) |
| | 156 | { |
| | 157 | int i; |
| | 158 | int alarms_printed = 0; |
| | 159 | |
| | 160 | for (i = 0; i < limit_count; i++) { |
| | 161 | if (!(i & 1)) { |
| | 162 | if (i) |
| | 163 | printf("\n%*s", label_size + 10, ""); |
| | 164 | printf("("); |
| | 165 | } else { |
| | 166 | printf(", "); |
| | 167 | } |
| | 168 | printf(fmt, limits[i].name, limits[i].value, |
| | 169 | limits[i].unit); |
| | 170 | if ((i & 1) || i == limit_count - 1) { |
| | 171 | printf(")"); |
| | 172 | if (alarm_count && !alarms_printed) { |
| | 173 | print_alarms(alarms, alarm_count, |
| | 174 | (i & 1) ? 0 : 16); |
| | 175 | alarms_printed = 1; |
| | 176 | } |
| | 177 | } |
| | 178 | } |
| | 179 | if (alarm_count && !alarms_printed) |
| | 180 | print_alarms(alarms, alarm_count, 32); |
| | 181 | } |
| | 182 | |
| | 183 | /* |
| | 184 | * Get sensor limit information. |
| | 185 | * *num_limits and *num_alarms must be initialized by the caller. |
| | 186 | */ |
| | 187 | static void get_sensor_limit_data(const sensors_chip_name *name, |
| | 188 | const sensors_feature *feature, |
| | 189 | const struct sensor_subfeature_list *sfl, |
| | 190 | struct sensor_subfeature_data *limits, |
| | 191 | int max_limits, |
| | 192 | int *num_limits, |
| | 193 | struct sensor_subfeature_data *alarms, |
| | 194 | int max_alarms, |
| | 195 | int *num_alarms) |
| | 196 | { |
| | 197 | const sensors_subfeature *sf; |
| | 198 | |
| | 199 | for (; sfl->subfeature >= 0; sfl++) { |
| | 200 | sf = sensors_get_subfeature(name, feature, sfl->subfeature); |
| | 201 | if (sf) { |
| | 202 | if (sfl->alarm) { |
| | 203 | /* |
| | 204 | * Only queue alarm subfeatures if the alarm |
| | 205 | * is active, and don't store the alarm value |
| | 206 | * (it is implied to be active if queued). |
| | 207 | */ |
| | 208 | if (get_value(name, sf)) { |
| | 209 | if (*num_alarms >= max_alarms) { |
| | 210 | fprintf(stderr, |
| | 211 | "Not enough %s buffers (%d)\n", |
| | 212 | "alarm", max_alarms); |
| | 213 | } else { |
| | 214 | alarms[*num_alarms].name = sfl->name; |
| | 215 | (*num_alarms)++; |
| | 216 | } |
| | 217 | } |
| | 218 | } else { |
| | 219 | /* |
| | 220 | * Always queue limit subfeatures with their value. |
| | 221 | */ |
| | 222 | if (*num_limits >= max_limits) { |
| | 223 | fprintf(stderr, |
| | 224 | "Not enough %s buffers (%d)\n", |
| | 225 | "limit", max_limits); |
| | 226 | } else { |
| | 227 | limits[*num_limits].value = get_value(name, sf); |
| | 228 | limits[*num_limits].name = sfl->name; |
| | 229 | (*num_limits)++; |
| | 230 | } |
| | 231 | } |
| | 232 | if (sfl->exists) { |
| | 233 | get_sensor_limit_data(name, feature, sfl->exists, |
| | 234 | limits, max_limits, num_limits, |
| | 235 | alarms, max_alarms, num_alarms); |
| | 236 | } |
| | 237 | } |
| | 238 | } |
| | 239 | } |
| | 240 | |
| | 241 | static const struct sensor_subfeature_list temp_max_sensors[] = { |
| | 242 | { SENSORS_SUBFEATURE_TEMP_MAX_HYST, NULL, 0, "hyst" }, |
| | 243 | { -1, NULL, 0, NULL } |
| | 244 | }; |
| | 245 | |
| | 246 | static const struct sensor_subfeature_list temp_crit_sensors[] = { |
| | 247 | { SENSORS_SUBFEATURE_TEMP_CRIT_HYST, NULL, 0, "crit hyst" }, |
| | 248 | { -1, NULL, 0, NULL } |
| | 249 | }; |
| | 250 | |
| | 251 | static const struct sensor_subfeature_list temp_emergency_sensors[] = { |
| | 252 | { SENSORS_SUBFEATURE_TEMP_EMERGENCY_HYST, NULL, 0, |
| | 253 | "emerg hyst" }, |
| | 254 | { -1, NULL, 0, NULL } |
| | 255 | }; |
| | 256 | |
| | 257 | static const struct sensor_subfeature_list temp_sensors[] = { |
| | 258 | { SENSORS_SUBFEATURE_TEMP_ALARM, NULL, 1, NULL }, |
| | 259 | { SENSORS_SUBFEATURE_TEMP_LCRIT_ALARM, NULL, 1, "LCRIT" }, |
| | 260 | { SENSORS_SUBFEATURE_TEMP_MIN_ALARM, NULL, 1, "LOW" }, |
| | 261 | { SENSORS_SUBFEATURE_TEMP_MAX_ALARM, NULL, 1, "HIGH" }, |
| | 262 | { SENSORS_SUBFEATURE_TEMP_CRIT_ALARM, NULL, 1, "CRIT" }, |
| | 263 | { SENSORS_SUBFEATURE_TEMP_EMERGENCY_ALARM, NULL, 1, "EMERGENCY" }, |
| | 264 | { SENSORS_SUBFEATURE_TEMP_MIN, NULL, 0, "low" }, |
| | 265 | { SENSORS_SUBFEATURE_TEMP_MAX, temp_max_sensors, 0, "high" }, |
| | 266 | { SENSORS_SUBFEATURE_TEMP_LCRIT, NULL, 0, "crit low" }, |
| | 267 | { SENSORS_SUBFEATURE_TEMP_CRIT, temp_crit_sensors, 0, "crit" }, |
| | 268 | { SENSORS_SUBFEATURE_TEMP_EMERGENCY, temp_emergency_sensors, 0, |
| | 269 | "emerg" }, |
| | 270 | { -1, NULL, 0, NULL } |
| | 271 | }; |
| 169 | | |
| 170 | | sf = sensors_get_subfeature(name, feature, |
| 171 | | SENSORS_SUBFEATURE_TEMP_ALARM); |
| 172 | | alarm = sf && get_value(name, sf); |
| 173 | | |
| 174 | | sfmin = sensors_get_subfeature(name, feature, |
| 175 | | SENSORS_SUBFEATURE_TEMP_MIN); |
| 176 | | sfmax = sensors_get_subfeature(name, feature, |
| 177 | | SENSORS_SUBFEATURE_TEMP_MAX); |
| 178 | | sfcrit = sensors_get_subfeature(name, feature, |
| 179 | | SENSORS_SUBFEATURE_TEMP_CRIT); |
| 180 | | if (sfmax) { |
| 181 | | sf = sensors_get_subfeature(name, feature, |
| 182 | | SENSORS_SUBFEATURE_TEMP_MAX_ALARM); |
| 183 | | if (sf && get_value(name, sf)) |
| 184 | | alarm |= 1; |
| 185 | | |
| 186 | | if (sfmin) { |
| 187 | | limit1 = get_value(name, sfmin); |
| 188 | | s1 = "low"; |
| 189 | | limit2 = get_value(name, sfmax); |
| 190 | | s2 = "high"; |
| 191 | | |
| 192 | | sf = sensors_get_subfeature(name, feature, |
| 193 | | SENSORS_SUBFEATURE_TEMP_MIN_ALARM); |
| 194 | | if (sf && get_value(name, sf)) |
| 195 | | alarm |= 1; |
| 196 | | } else { |
| 197 | | limit1 = get_value(name, sfmax); |
| 198 | | s1 = "high"; |
| 199 | | |
| 200 | | sfhyst = sensors_get_subfeature(name, feature, |
| 201 | | SENSORS_SUBFEATURE_TEMP_MAX_HYST); |
| 202 | | if (sfhyst) { |
| 203 | | limit2 = get_value(name, sfhyst); |
| 204 | | s2 = "hyst"; |
| 205 | | } else if (sfcrit) { |
| 206 | | limit2 = get_value(name, sfcrit); |
| 207 | | s2 = "crit"; |
| 208 | | |
| 209 | | sf = sensors_get_subfeature(name, feature, |
| 210 | | SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); |
| 211 | | if (sf && get_value(name, sf)) |
| 212 | | alarm |= 1; |
| 213 | | crit_displayed = 1; |
| 214 | | } else { |
| 215 | | limit2 = 0; |
| 216 | | s2 = NULL; |
| 217 | | } |
| 218 | | } |
| 219 | | } else if (sfcrit) { |
| 220 | | limit1 = get_value(name, sfcrit); |
| 221 | | s1 = "crit"; |
| 222 | | |
| 223 | | sfhyst = sensors_get_subfeature(name, feature, |
| 224 | | SENSORS_SUBFEATURE_TEMP_CRIT_HYST); |
| 225 | | if (sfhyst) { |
| 226 | | limit2 = get_value(name, sfhyst); |
| 227 | | s2 = "hyst"; |
| 228 | | } else { |
| 229 | | limit2 = 0; |
| 230 | | s2 = NULL; |
| 231 | | } |
| 232 | | |
| 233 | | sf = sensors_get_subfeature(name, feature, |
| 234 | | SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); |
| 235 | | if (sf && get_value(name, sf)) |
| 236 | | alarm |= 1; |
| 237 | | crit_displayed = 1; |
| 238 | | } else { |
| 239 | | limit1 = limit2 = 0; |
| 240 | | s1 = s2 = NULL; |
| 241 | | } |
| 242 | | |
| 259 | | print_temp_limits(limit1, limit2, s1, s2, alarm); |
| 260 | | |
| 261 | | if (!crit_displayed && sfcrit) { |
| 262 | | limit1 = get_value(name, sfcrit); |
| 263 | | s1 = "crit"; |
| 264 | | |
| 265 | | sfhyst = sensors_get_subfeature(name, feature, |
| 266 | | SENSORS_SUBFEATURE_TEMP_CRIT_HYST); |
| 267 | | if (sfhyst) { |
| 268 | | limit2 = get_value(name, sfhyst); |
| 269 | | s2 = "hyst"; |
| 270 | | } else { |
| 271 | | limit2 = 0; |
| 272 | | s2 = NULL; |
| 273 | | } |
| 274 | | |
| 275 | | sf = sensors_get_subfeature(name, feature, |
| 276 | | SENSORS_SUBFEATURE_TEMP_CRIT_ALARM); |
| 277 | | alarm = sf && get_value(name, sf); |
| 278 | | |
| 279 | | printf("\n%*s", label_size + 10, ""); |
| 280 | | print_temp_limits(limit1, limit2, s1, s2, alarm); |
| 281 | | } |
| | 308 | |
| | 309 | sensor_count = alarm_count = 0; |
| | 310 | get_sensor_limit_data(name, feature, temp_sensors, |
| | 311 | sensors, ARRAY_SIZE(sensors), &sensor_count, |
| | 312 | alarms, ARRAY_SIZE(alarms), &alarm_count); |
| | 313 | |
| | 314 | for (i = 0; i < sensor_count; i++) { |
| | 315 | if (fahrenheit) |
| | 316 | sensors[i].value = deg_ctof(sensors[i].value); |
| | 317 | sensors[i].unit = degstr; |
| | 318 | } |
| | 319 | |
| | 320 | print_limits(sensors, sensor_count, alarms, alarm_count, label_size, |
| | 321 | "%-4s = %+5.1f%s"); |
| | 345 | static const struct sensor_subfeature_list voltage_sensors[] = { |
| | 346 | { SENSORS_SUBFEATURE_IN_ALARM, NULL, 1, NULL }, |
| | 347 | { SENSORS_SUBFEATURE_IN_LCRIT_ALARM, NULL, 1, "LCRIT" }, |
| | 348 | { SENSORS_SUBFEATURE_IN_MIN_ALARM, NULL, 1, "MIN" }, |
| | 349 | { SENSORS_SUBFEATURE_IN_MAX_ALARM, NULL, 1, "MAX" }, |
| | 350 | { SENSORS_SUBFEATURE_IN_CRIT_ALARM, NULL, 1, "CRIT" }, |
| | 351 | { SENSORS_SUBFEATURE_IN_LCRIT, NULL, 0, "crit min" }, |
| | 352 | { SENSORS_SUBFEATURE_IN_MIN, NULL, 0, "min" }, |
| | 353 | { SENSORS_SUBFEATURE_IN_MAX, NULL, 0, "max" }, |
| | 354 | { SENSORS_SUBFEATURE_IN_CRIT, NULL, 0, "crit max" }, |
| | 355 | { -1, NULL, 0, NULL } |
| | 356 | }; |
| | 357 | |
| 326 | | printf(" N/A"); |
| 327 | | |
| 328 | | sfmin = sensors_get_subfeature(name, feature, |
| 329 | | SENSORS_SUBFEATURE_IN_MIN); |
| 330 | | sfmax = sensors_get_subfeature(name, feature, |
| 331 | | SENSORS_SUBFEATURE_IN_MAX); |
| 332 | | if (sfmin && sfmax) |
| 333 | | printf(" (min = %+6.2f V, max = %+6.2f V)", |
| 334 | | get_value(name, sfmin), |
| 335 | | get_value(name, sfmax)); |
| 336 | | else if (sfmin) |
| 337 | | printf(" (min = %+6.2f V)", |
| 338 | | get_value(name, sfmin)); |
| 339 | | else if (sfmax) |
| 340 | | printf(" (max = %+6.2f V)", |
| 341 | | get_value(name, sfmax)); |
| 342 | | |
| 343 | | sf = sensors_get_subfeature(name, feature, |
| 344 | | SENSORS_SUBFEATURE_IN_ALARM); |
| 345 | | sfmin = sensors_get_subfeature(name, feature, |
| 346 | | SENSORS_SUBFEATURE_IN_MIN_ALARM); |
| 347 | | sfmax = sensors_get_subfeature(name, feature, |
| 348 | | SENSORS_SUBFEATURE_IN_MAX_ALARM); |
| 349 | | if (sfmin || sfmax) { |
| 350 | | alarm_max = sfmax ? get_value(name, sfmax) : 0; |
| 351 | | alarm_min = sfmin ? get_value(name, sfmin) : 0; |
| 352 | | |
| 353 | | if (alarm_min || alarm_max) { |
| 354 | | printf(" ALARM ("); |
| 355 | | |
| 356 | | if (alarm_min) |
| 357 | | printf("MIN"); |
| 358 | | if (alarm_max) |
| 359 | | printf("%sMAX", (alarm_min) ? ", " : ""); |
| 360 | | |
| 361 | | printf(")"); |
| 362 | | } |
| 363 | | } else if (sf) { |
| 364 | | printf(" %s", |
| 365 | | get_value(name, sf) ? "ALARM" : ""); |
| 366 | | } |
| | 382 | printf(" N/A "); |
| | 383 | |
| | 384 | sensor_count = alarm_count = 0; |
| | 385 | get_sensor_limit_data(name, feature, voltage_sensors, |
| | 386 | sensors, ARRAY_SIZE(sensors), &sensor_count, |
| | 387 | alarms, ARRAY_SIZE(alarms), &alarm_count); |
| | 388 | |
| | 389 | print_limits(sensors, sensor_count, alarms, alarm_count, label_size, |
| | 390 | "%s = %+6.2f V"); |
| | 482 | static const struct sensor_subfeature_list power_common_sensors[] = { |
| | 483 | { SENSORS_SUBFEATURE_POWER_ALARM, NULL, 1, NULL }, |
| | 484 | { SENSORS_SUBFEATURE_POWER_MAX_ALARM, NULL, 1, "MAX" }, |
| | 485 | { SENSORS_SUBFEATURE_POWER_CRIT_ALARM, NULL, 1, "CRIT" }, |
| | 486 | { SENSORS_SUBFEATURE_POWER_CAP_ALARM, NULL, 1, "CAP" }, |
| | 487 | { SENSORS_SUBFEATURE_POWER_MAX, NULL, 0, "max" }, |
| | 488 | { SENSORS_SUBFEATURE_POWER_CRIT, NULL, 0, "crit" }, |
| | 489 | { SENSORS_SUBFEATURE_POWER_CAP, NULL, 0, "cap" }, |
| | 490 | { -1, NULL, 0, NULL } |
| | 491 | }; |
| | 492 | |
| | 493 | static const struct sensor_subfeature_list power_inst_sensors[] = { |
| | 494 | { SENSORS_SUBFEATURE_POWER_INPUT_LOWEST, NULL, 0, "lowest" }, |
| | 495 | { SENSORS_SUBFEATURE_POWER_INPUT_HIGHEST, NULL, 0, "highest" }, |
| | 496 | { -1, NULL, 0, NULL } |
| | 497 | }; |
| | 498 | |
| | 499 | static const struct sensor_subfeature_list power_avg_sensors[] = { |
| | 500 | { SENSORS_SUBFEATURE_POWER_AVERAGE_LOWEST, NULL, 0, "lowest" }, |
| | 501 | { SENSORS_SUBFEATURE_POWER_AVERAGE_HIGHEST, NULL, 0, "highest" }, |
| | 502 | { SENSORS_SUBFEATURE_POWER_AVERAGE_INTERVAL, NULL, 0, |
| | 503 | "interval" }, |
| | 504 | { -1, NULL, 0, NULL } |
| | 505 | }; |
| | 506 | |
| | 633 | static const struct sensor_subfeature_list current_sensors[] = { |
| | 634 | { SENSORS_SUBFEATURE_CURR_ALARM, NULL, 1, NULL }, |
| | 635 | { SENSORS_SUBFEATURE_CURR_LCRIT_ALARM, NULL, 1, "LCRIT" }, |
| | 636 | { SENSORS_SUBFEATURE_CURR_MIN_ALARM, NULL, 1, "MIN" }, |
| | 637 | { SENSORS_SUBFEATURE_CURR_MAX_ALARM, NULL, 1, "MAX" }, |
| | 638 | { SENSORS_SUBFEATURE_CURR_CRIT_ALARM, NULL, 1, "CRIT" }, |
| | 639 | { SENSORS_SUBFEATURE_CURR_LCRIT, NULL, 0, "crit min" }, |
| | 640 | { SENSORS_SUBFEATURE_CURR_MIN, NULL, 0, "min" }, |
| | 641 | { SENSORS_SUBFEATURE_CURR_MAX, NULL, 0, "max" }, |
| | 642 | { SENSORS_SUBFEATURE_CURR_CRIT, NULL, 0, "crit max" }, |
| | 643 | { -1, NULL, 0, NULL } |
| | 644 | }; |
| | 645 | |
| 624 | | printf(" N/A"); |
| 625 | | |
| 626 | | sfmin = sensors_get_subfeature(name, feature, |
| 627 | | SENSORS_SUBFEATURE_CURR_MIN); |
| 628 | | sfmax = sensors_get_subfeature(name, feature, |
| 629 | | SENSORS_SUBFEATURE_CURR_MAX); |
| 630 | | if (sfmin && sfmax) |
| 631 | | printf(" (min = %+6.2f A, max = %+6.2f A)", |
| 632 | | get_value(name, sfmin), |
| 633 | | get_value(name, sfmax)); |
| 634 | | else if (sfmin) |
| 635 | | printf(" (min = %+6.2f A)", |
| 636 | | get_value(name, sfmin)); |
| 637 | | else if (sfmax) |
| 638 | | printf(" (max = %+6.2f A)", |
| 639 | | get_value(name, sfmax)); |
| 640 | | |
| 641 | | sf = sensors_get_subfeature(name, feature, |
| 642 | | SENSORS_SUBFEATURE_CURR_ALARM); |
| 643 | | sfmin = sensors_get_subfeature(name, feature, |
| 644 | | SENSORS_SUBFEATURE_CURR_MIN_ALARM); |
| 645 | | sfmax = sensors_get_subfeature(name, feature, |
| 646 | | SENSORS_SUBFEATURE_CURR_MAX_ALARM); |
| 647 | | if (sfmin || sfmax) { |
| 648 | | alarm_max = sfmax ? get_value(name, sfmax) : 0; |
| 649 | | alarm_min = sfmin ? get_value(name, sfmin) : 0; |
| 650 | | |
| 651 | | if (alarm_min || alarm_max) { |
| 652 | | printf(" ALARM ("); |
| 653 | | |
| 654 | | if (alarm_min) |
| 655 | | printf("MIN"); |
| 656 | | if (alarm_max) |
| 657 | | printf("%sMAX", (alarm_min) ? ", " : ""); |
| 658 | | |
| 659 | | printf(")"); |
| 660 | | } |
| 661 | | } else if (sf) { |
| 662 | | printf(" %s", |
| 663 | | get_value(name, sf) ? "ALARM" : ""); |
| 664 | | } |
| | 670 | printf(" N/A "); |
| | 671 | |
| | 672 | sensor_count = alarm_count = 0; |
| | 673 | get_sensor_limit_data(name, feature, current_sensors, |
| | 674 | sensors, ARRAY_SIZE(sensors), &sensor_count, |
| | 675 | alarms, ARRAY_SIZE(alarms), &alarm_count); |
| | 676 | |
| | 677 | print_limits(sensors, sensor_count, alarms, alarm_count, label_size, |
| | 678 | "%s = %+6.2f A"); |