1 /* 2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Sun Microsystems, Inc. or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 #include <string.h> 34 #include <math.h> 35 36 #include <ipmitool/ipmi.h> 37 #include <ipmitool/helper.h> 38 #include <ipmitool/log.h> 39 #include <ipmitool/ipmi_intf.h> 40 #include <ipmitool/ipmi_sdr.h> 41 #include <ipmitool/ipmi_sel.h> 42 #include <ipmitool/ipmi_sensor.h> 43 44 extern int verbose; 45 void print_sensor_get_usage(); 46 void print_sensor_thresh_usage(); 47 48 // Macro's for Reading the current sensor Data. 49 #define SCANNING_DISABLED 0x40 50 #define READING_UNAVAILABLE 0x20 51 #define INVALID_THRESHOLD "Invalid Threshold data values. Cannot Set Threshold Data." 52 // static 53 int 54 ipmi_sensor_get_sensor_reading_factors( 55 struct ipmi_intf * intf, 56 struct sdr_record_full_sensor * sensor, 57 uint8_t reading) 58 { 59 struct ipmi_rq req; 60 struct ipmi_rs * rsp; 61 uint8_t req_data[2]; 62 63 char id[17]; 64 65 if (intf == NULL || sensor == NULL) 66 return -1; 67 68 memset(id, 0, sizeof(id)); 69 memcpy(id, sensor->id_string, 16); 70 71 req_data[0] = sensor->cmn.keys.sensor_num; 72 req_data[1] = reading; 73 74 memset(&req, 0, sizeof(req)); 75 req.msg.netfn = IPMI_NETFN_SE; 76 req.msg.lun = sensor->cmn.keys.lun; 77 req.msg.cmd = GET_SENSOR_FACTORS; 78 req.msg.data = req_data; 79 req.msg.data_len = sizeof(req_data); 80 81 rsp = intf->sendrecv(intf, &req); 82 83 if (rsp == NULL) { 84 lprintf(LOG_ERR, "Error updating reading factor for sensor %s (#%02x)", 85 id, sensor->cmn.keys.sensor_num); 86 return -1; 87 } else if (rsp->ccode) { 88 return -1; 89 } else { 90 /* Update SDR copy with updated Reading Factors for this reading */ 91 /* Note: 92 * The Format of the returned data is exactly as in the SDR definition (Little Endian Format), 93 * therefore we can use raw copy operation here. 94 * Note: rsp->data[0] would point to the next valid entry in the sampling table 95 */ 96 // BUGBUG: uses 'hardcoded' length information from SDR Definition 97 memcpy(&sensor->mtol, &rsp->data[1], sizeof(sensor->mtol)); 98 memcpy(&sensor->bacc, &rsp->data[3], sizeof(sensor->bacc)); 99 return 0; 100 } 101 102 } 103 104 static 105 struct ipmi_rs * 106 ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf, 107 uint8_t sensor, 108 uint8_t threshold, uint8_t setting, 109 uint8_t target, uint8_t lun, uint8_t channel) 110 { 111 struct ipmi_rq req; 112 static struct sensor_set_thresh_rq set_thresh_rq; 113 struct ipmi_rs *rsp; 114 uint8_t bridged_request = 0; 115 uint32_t save_addr; 116 uint32_t save_channel; 117 118 memset(&set_thresh_rq, 0, sizeof (set_thresh_rq)); 119 set_thresh_rq.sensor_num = sensor; 120 set_thresh_rq.set_mask = threshold; 121 if (threshold == UPPER_NON_RECOV_SPECIFIED) 122 set_thresh_rq.upper_non_recov = setting; 123 else if (threshold == UPPER_CRIT_SPECIFIED) 124 set_thresh_rq.upper_crit = setting; 125 else if (threshold == UPPER_NON_CRIT_SPECIFIED) 126 set_thresh_rq.upper_non_crit = setting; 127 else if (threshold == LOWER_NON_CRIT_SPECIFIED) 128 set_thresh_rq.lower_non_crit = setting; 129 else if (threshold == LOWER_CRIT_SPECIFIED) 130 set_thresh_rq.lower_crit = setting; 131 else if (threshold == LOWER_NON_RECOV_SPECIFIED) 132 set_thresh_rq.lower_non_recov = setting; 133 else 134 return NULL; 135 136 if (BRIDGE_TO_SENSOR(intf, target, channel)) { 137 bridged_request = 1; 138 save_addr = intf->target_addr; 139 intf->target_addr = target; 140 save_channel = intf->target_channel; 141 intf->target_channel = channel; 142 } 143 memset(&req, 0, sizeof (req)); 144 req.msg.netfn = IPMI_NETFN_SE; 145 req.msg.lun = lun; 146 req.msg.cmd = SET_SENSOR_THRESHOLDS; 147 req.msg.data = (uint8_t *) & set_thresh_rq; 148 req.msg.data_len = sizeof (set_thresh_rq); 149 150 rsp = intf->sendrecv(intf, &req); 151 if (bridged_request) { 152 intf->target_addr = save_addr; 153 intf->target_channel = save_channel; 154 } 155 return rsp; 156 } 157 158 static int 159 ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, 160 struct sdr_record_common_sensor *sensor, 161 uint8_t sdr_record_type) 162 { 163 const char *id; 164 struct sensor_reading *sr; 165 166 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); 167 168 if (sr == NULL) { 169 return -1; 170 } 171 172 if (csv_output) { 173 /* NOT IMPLEMENTED */ 174 } else { 175 if (verbose == 0) { 176 /* output format 177 * id value units status thresholds.... 178 */ 179 printf("%-16s ", sr->s_id); 180 if (sr->s_reading_valid) { 181 if (sr->s_has_analog_value) { 182 /* don't show discrete component */ 183 printf("| %-10s | %-10s | %-6s", 184 sr->s_a_str, sr->s_a_units, "ok"); 185 } else { 186 printf("| 0x%-8x | %-10s | 0x%02x%02x", 187 sr->s_reading, "discrete", 188 sr->s_data2, sr->s_data3); 189 } 190 } else { 191 printf("| %-10s | %-10s | %-6s", 192 "na", "discrete", "na"); 193 } 194 printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", 195 "na", "na", "na", "na", "na", "na"); 196 197 printf("\n"); 198 } else { 199 printf("Sensor ID : %s (0x%x)\n", 200 sr->s_id, sensor->keys.sensor_num); 201 printf(" Entity ID : %d.%d\n", 202 sensor->entity.id, sensor->entity.instance); 203 printf(" Sensor Type (Discrete): %s\n", 204 ipmi_sdr_get_sensor_type_desc(sensor->sensor. 205 type)); 206 if( sr->s_reading_valid ) 207 { 208 if (sr->s_has_analog_value) { 209 printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units); 210 } 211 ipmi_sdr_print_discrete_state("States Asserted", 212 sensor->sensor.type, 213 sensor->event_type, 214 sr->s_data2, 215 sr->s_data3); 216 printf("\n"); 217 } else { 218 printf(" Unable to read sensor: Device Not Present\n\n"); 219 } 220 } 221 } 222 223 return (sr->s_reading_valid ? 0 : -1 ); 224 } 225 226 static void 227 print_thresh_setting(struct sdr_record_full_sensor *full, 228 uint8_t thresh_is_avail, uint8_t setting, 229 const char *field_sep, 230 const char *analog_fmt, 231 const char *discrete_fmt, 232 const char *na_fmt) 233 { 234 printf("%s", field_sep); 235 if (!thresh_is_avail) { 236 printf(na_fmt, "na"); 237 return; 238 } 239 if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { 240 printf(analog_fmt, sdr_convert_sensor_reading (full, setting)); 241 } else { 242 printf(discrete_fmt, setting); 243 } 244 } 245 246 static int 247 ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf, 248 struct sdr_record_common_sensor *sensor, 249 uint8_t sdr_record_type) 250 { 251 int thresh_available = 1; 252 struct ipmi_rs *rsp; 253 struct sensor_reading *sr; 254 255 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); 256 257 if (sr == NULL) { 258 return -1; 259 } 260 261 const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns"); 262 263 /* 264 * Get sensor thresholds 265 */ 266 rsp = ipmi_sdr_get_sensor_thresholds(intf, 267 sensor->keys.sensor_num, sensor->keys.owner_id, 268 sensor->keys.lun, sensor->keys.channel); 269 270 if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0)) 271 thresh_available = 0; 272 273 if (csv_output) { 274 /* NOT IMPLEMENTED */ 275 } else { 276 if (verbose == 0) { 277 /* output format 278 * id value units status thresholds.... 279 */ 280 printf("%-16s ", sr->s_id); 281 if (sr->s_reading_valid) { 282 if (sr->s_has_analog_value) 283 printf("| %-10.3f | %-10s | %-6s", 284 sr->s_a_val, sr->s_a_units, thresh_status); 285 else 286 printf("| 0x%-8x | %-10s | %-6s", 287 sr->s_reading, sr->s_a_units, thresh_status); 288 } else { 289 printf("| %-10s | %-10s | %-6s", 290 "na", sr->s_a_units, "na"); 291 } 292 if (thresh_available && sr->full) { 293 #define PTS(bit, dataidx) { \ 294 print_thresh_setting(sr->full, rsp->data[0] & (bit), \ 295 rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \ 296 } 297 PTS(LOWER_NON_RECOV_SPECIFIED, 3); 298 PTS(LOWER_CRIT_SPECIFIED, 2); 299 PTS(LOWER_NON_CRIT_SPECIFIED, 1); 300 PTS(UPPER_NON_CRIT_SPECIFIED, 4); 301 PTS(UPPER_CRIT_SPECIFIED, 5); 302 PTS(UPPER_NON_RECOV_SPECIFIED, 6); 303 #undef PTS 304 } else { 305 printf 306 ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", 307 "na", "na", "na", "na", "na", "na"); 308 } 309 310 printf("\n"); 311 } else { 312 printf("Sensor ID : %s (0x%x)\n", 313 sr->s_id, sensor->keys.sensor_num); 314 315 printf(" Entity ID : %d.%d\n", 316 sensor->entity.id, sensor->entity.instance); 317 318 printf(" Sensor Type (Threshold) : %s\n", 319 ipmi_sdr_get_sensor_type_desc(sensor->sensor. 320 type)); 321 322 printf(" Sensor Reading : "); 323 if (sr->s_reading_valid) { 324 if (sr->full) { 325 uint16_t raw_tol = __TO_TOL(sr->full->mtol); 326 if (sr->s_has_analog_value) { 327 double tol = 328 sdr_convert_sensor_tolerance(sr->full, 329 raw_tol); 330 printf("%.*f (+/- %.*f) %s\n", 331 (sr->s_a_val == (int) 332 sr->s_a_val) ? 0 : 3, 333 sr->s_a_val, 334 (tol == (int) tol) ? 0 : 3, tol, 335 sr->s_a_units); 336 } else { 337 printf("0x%x (+/- 0x%x) %s\n", 338 sr->s_reading, 339 raw_tol, 340 sr->s_a_units); 341 } 342 } else { 343 printf("0x%x %s\n", sr->s_reading, 344 sr->s_a_units); 345 } 346 printf(" Status : %s\n", thresh_status); 347 348 if (thresh_available) { 349 if (sr->full) { 350 #define PTS(bit, dataidx, str) { \ 351 print_thresh_setting(sr->full, rsp->data[0] & (bit), \ 352 rsp->data[(dataidx)], \ 353 (str), "%.3f\n", "0x%x\n", "%s\n"); \ 354 } 355 356 PTS(LOWER_NON_RECOV_SPECIFIED, 3, " Lower Non-Recoverable : "); 357 PTS(LOWER_CRIT_SPECIFIED, 2, " Lower Critical : "); 358 PTS(LOWER_NON_CRIT_SPECIFIED, 1, " Lower Non-Critical : "); 359 PTS(UPPER_NON_CRIT_SPECIFIED, 4, " Upper Non-Critical : "); 360 PTS(UPPER_CRIT_SPECIFIED, 5, " Upper Critical : "); 361 PTS(UPPER_NON_RECOV_SPECIFIED, 6, " Upper Non-Recoverable : "); 362 #undef PTS 363 364 } 365 ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, 366 sr->full ? sr->full->threshold.hysteresis.positive : 367 sr->compact->threshold.hysteresis.positive, 368 "Positive Hysteresis"); 369 370 ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, 371 sr->full ? sr->full->threshold.hysteresis.negative : 372 sr->compact->threshold.hysteresis.negative, 373 "Negative Hysteresis"); 374 } else { 375 printf(" Sensor Threshold Settings not available\n"); 376 } 377 } else { 378 printf(" Unable to read sensor: Device Not Present\n\n"); 379 } 380 381 ipmi_sdr_print_sensor_event_status(intf, 382 sensor->keys. 383 sensor_num, 384 sensor->sensor.type, 385 sensor->event_type, 386 ANALOG_SENSOR, 387 sensor->keys.owner_id, 388 sensor->keys.lun, 389 sensor->keys.channel); 390 ipmi_sdr_print_sensor_event_enable(intf, 391 sensor->keys. 392 sensor_num, 393 sensor->sensor.type, 394 sensor->event_type, 395 ANALOG_SENSOR, 396 sensor->keys.owner_id, 397 sensor->keys.lun, 398 sensor->keys.channel); 399 400 printf("\n"); 401 } 402 } 403 404 return (sr->s_reading_valid ? 0 : -1 ); 405 } 406 407 int 408 ipmi_sensor_print_fc(struct ipmi_intf *intf, 409 struct sdr_record_common_sensor *sensor, 410 uint8_t sdr_record_type) 411 { 412 if (IS_THRESHOLD_SENSOR(sensor)) 413 return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type); 414 else 415 return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type); 416 } 417 418 static int 419 ipmi_sensor_list(struct ipmi_intf *intf) 420 { 421 struct sdr_get_rs *header; 422 struct ipmi_sdr_iterator *itr; 423 int rc = 0; 424 425 lprintf(LOG_DEBUG, "Querying SDR for sensor list"); 426 427 itr = ipmi_sdr_start(intf, 0); 428 if (itr == NULL) { 429 lprintf(LOG_ERR, "Unable to open SDR for reading"); 430 return -1; 431 } 432 433 while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { 434 uint8_t *rec; 435 436 rec = ipmi_sdr_get_record(intf, header, itr); 437 if (rec == NULL) { 438 lprintf(LOG_DEBUG, "rec == NULL"); 439 continue; 440 } 441 442 switch (header->type) { 443 case SDR_RECORD_TYPE_FULL_SENSOR: 444 case SDR_RECORD_TYPE_COMPACT_SENSOR: 445 ipmi_sensor_print_fc(intf, 446 (struct 447 sdr_record_common_sensor *) 448 rec, 449 header->type); 450 break; 451 } 452 free(rec); 453 rec = NULL; 454 455 /* fix for CR6604909: */ 456 /* mask failure of individual reads in sensor list command */ 457 /* rc = (r == 0) ? rc : r; */ 458 } 459 460 ipmi_sdr_end(intf, itr); 461 462 return rc; 463 } 464 465 static const struct valstr threshold_vals[] = { 466 {UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"}, 467 {UPPER_CRIT_SPECIFIED, "Upper Critical"}, 468 {UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"}, 469 {LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"}, 470 {LOWER_CRIT_SPECIFIED, "Lower Critical"}, 471 {LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"}, 472 {0x00, NULL}, 473 }; 474 475 static int 476 __ipmi_sensor_set_threshold(struct ipmi_intf *intf, 477 uint8_t num, uint8_t mask, uint8_t setting, 478 uint8_t target, uint8_t lun, uint8_t channel) 479 { 480 struct ipmi_rs *rsp; 481 482 rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting, 483 target, lun, channel); 484 485 if (rsp == NULL) { 486 lprintf(LOG_ERR, "Error setting threshold"); 487 return -1; 488 } 489 if (rsp->ccode > 0) { 490 lprintf(LOG_ERR, "Error setting threshold: %s", 491 val2str(rsp->ccode, completion_code_vals)); 492 return -1; 493 } 494 495 return 0; 496 } 497 498 static uint8_t 499 __ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value) 500 { 501 if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */ 502 /* Has an analog reading and supports mx+b */ 503 return sdr_convert_sensor_value_to_raw(full, value); 504 } 505 else { 506 /* Does not have an analog reading and/or does not support mx+b */ 507 if (value > 255) { 508 return 255; 509 } 510 else if (value < 0) { 511 return 0; 512 } 513 else { 514 return (uint8_t )value; 515 } 516 } 517 } 518 519 static int 520 ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv) 521 { 522 char *id, *thresh; 523 uint8_t settingMask = 0; 524 double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0; 525 int allUpper = 0, allLower = 0; 526 int ret = 0; 527 struct ipmi_rs *rsp; 528 int i =0; 529 double val[10] = {0}; 530 531 struct sdr_record_list *sdr; 532 533 if (argc < 3 || strncmp(argv[0], "help", 4) == 0) { 534 print_sensor_thresh_usage(); 535 return 0; 536 } 537 538 id = argv[0]; 539 thresh = argv[1]; 540 541 if (strncmp(thresh, "upper", 5) == 0) { 542 if (argc < 5) { 543 lprintf(LOG_ERR, 544 "usage: sensor thresh <id> upper <unc> <ucr> <unr>"); 545 return -1; 546 } 547 allUpper = 1; 548 if (str2double(argv[2], &setting1) != 0) { 549 lprintf(LOG_ERR, "Given unc '%s' is invalid.", 550 argv[2]); 551 return (-1); 552 } 553 if (str2double(argv[3], &setting2) != 0) { 554 lprintf(LOG_ERR, "Given ucr '%s' is invalid.", 555 argv[3]); 556 return (-1); 557 } 558 if (str2double(argv[4], &setting3) != 0) { 559 lprintf(LOG_ERR, "Given unr '%s' is invalid.", 560 argv[4]); 561 return (-1); 562 } 563 } else if (strncmp(thresh, "lower", 5) == 0) { 564 if (argc < 5) { 565 lprintf(LOG_ERR, 566 "usage: sensor thresh <id> lower <lnr> <lcr> <lnc>"); 567 return -1; 568 } 569 allLower = 1; 570 if (str2double(argv[2], &setting1) != 0) { 571 lprintf(LOG_ERR, "Given lnc '%s' is invalid.", 572 argv[2]); 573 return (-1); 574 } 575 if (str2double(argv[3], &setting2) != 0) { 576 lprintf(LOG_ERR, "Given lcr '%s' is invalid.", 577 argv[3]); 578 return (-1); 579 } 580 if (str2double(argv[4], &setting3) != 0) { 581 lprintf(LOG_ERR, "Given lnr '%s' is invalid.", 582 argv[4]); 583 return (-1); 584 } 585 } else { 586 if (strncmp(thresh, "unr", 3) == 0) 587 settingMask = UPPER_NON_RECOV_SPECIFIED; 588 else if (strncmp(thresh, "ucr", 3) == 0) 589 settingMask = UPPER_CRIT_SPECIFIED; 590 else if (strncmp(thresh, "unc", 3) == 0) 591 settingMask = UPPER_NON_CRIT_SPECIFIED; 592 else if (strncmp(thresh, "lnc", 3) == 0) 593 settingMask = LOWER_NON_CRIT_SPECIFIED; 594 else if (strncmp(thresh, "lcr", 3) == 0) 595 settingMask = LOWER_CRIT_SPECIFIED; 596 else if (strncmp(thresh, "lnr", 3) == 0) 597 settingMask = LOWER_NON_RECOV_SPECIFIED; 598 else { 599 lprintf(LOG_ERR, 600 "Valid threshold '%s' for sensor '%s' not specified!", 601 thresh, id); 602 return -1; 603 } 604 if (str2double(argv[2], &setting1) != 0) { 605 lprintf(LOG_ERR, 606 "Given %s threshold value '%s' is invalid.", 607 thresh, argv[2]); 608 return (-1); 609 } 610 } 611 612 printf("Locating sensor record '%s'...\n", id); 613 614 /* lookup by sensor name */ 615 sdr = ipmi_sdr_find_sdr_byid(intf, id); 616 if (sdr == NULL) { 617 lprintf(LOG_ERR, "Sensor data record not found!"); 618 return -1; 619 } 620 621 if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) { 622 lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type); 623 return -1; 624 } 625 626 if (!IS_THRESHOLD_SENSOR(sdr->record.common)) { 627 lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type); 628 return -1; 629 } 630 631 632 if (allUpper) { 633 settingMask = UPPER_NON_CRIT_SPECIFIED; 634 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 635 sdr->record.full->id_string, 636 val2str(settingMask, threshold_vals), setting1); 637 ret = __ipmi_sensor_set_threshold(intf, 638 sdr->record.common->keys. 639 sensor_num, settingMask, 640 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), 641 sdr->record.common->keys.owner_id, 642 sdr->record.common->keys.lun, 643 sdr->record.common->keys.channel); 644 645 settingMask = UPPER_CRIT_SPECIFIED; 646 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 647 sdr->record.full->id_string, 648 val2str(settingMask, threshold_vals), setting2); 649 ret = __ipmi_sensor_set_threshold(intf, 650 sdr->record.common->keys. 651 sensor_num, settingMask, 652 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), 653 sdr->record.common->keys.owner_id, 654 sdr->record.common->keys.lun, 655 sdr->record.common->keys.channel); 656 657 settingMask = UPPER_NON_RECOV_SPECIFIED; 658 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 659 sdr->record.full->id_string, 660 val2str(settingMask, threshold_vals), setting3); 661 ret = __ipmi_sensor_set_threshold(intf, 662 sdr->record.common->keys. 663 sensor_num, settingMask, 664 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), 665 sdr->record.common->keys.owner_id, 666 sdr->record.common->keys.lun, 667 sdr->record.common->keys.channel); 668 } else if (allLower) { 669 settingMask = LOWER_NON_RECOV_SPECIFIED; 670 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 671 sdr->record.full->id_string, 672 val2str(settingMask, threshold_vals), setting1); 673 ret = __ipmi_sensor_set_threshold(intf, 674 sdr->record.common->keys. 675 sensor_num, settingMask, 676 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), 677 sdr->record.common->keys.owner_id, 678 sdr->record.common->keys.lun, 679 sdr->record.common->keys.channel); 680 681 settingMask = LOWER_CRIT_SPECIFIED; 682 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 683 sdr->record.full->id_string, 684 val2str(settingMask, threshold_vals), setting2); 685 ret = __ipmi_sensor_set_threshold(intf, 686 sdr->record.common->keys. 687 sensor_num, settingMask, 688 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), 689 sdr->record.common->keys.owner_id, 690 sdr->record.common->keys.lun, 691 sdr->record.common->keys.channel); 692 693 settingMask = LOWER_NON_CRIT_SPECIFIED; 694 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 695 sdr->record.full->id_string, 696 val2str(settingMask, threshold_vals), setting3); 697 ret = __ipmi_sensor_set_threshold(intf, 698 sdr->record.common->keys. 699 sensor_num, settingMask, 700 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), 701 sdr->record.common->keys.owner_id, 702 sdr->record.common->keys.lun, 703 sdr->record.common->keys.channel); 704 } else { 705 706 /* 707 * Current implementation doesn't check for the valid setting of upper non critical and other thresholds. 708 * In the below logic: 709 * Get all the current reading of the sensor i.e. unc, uc, lc,lnc. 710 * Validate the values given by the user. 711 * If the values are not correct, then popup with the Error message and return. 712 */ 713 /* 714 * Get current reading 715 */ 716 rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, 717 sdr->record.common->keys.sensor_num, 718 sdr->record.common->keys.owner_id, 719 sdr->record.common->keys.lun,sdr->record.common->keys.channel); 720 rsp = ipmi_sdr_get_sensor_thresholds(intf, 721 sdr->record.common->keys.sensor_num, 722 sdr->record.common->keys.owner_id, 723 sdr->record.common->keys.lun, 724 sdr->record.common->keys.channel); 725 if ((rsp == NULL) || (rsp->ccode > 0)) { 726 lprintf(LOG_ERR, "Sensor data record not found!"); 727 return -1; 728 } 729 for(i=1;i<=6;i++) { 730 val[i] = sdr_convert_sensor_reading(sdr->record.full, rsp->data[i]); 731 if(val[i] < 0) 732 val[i] = 0; 733 } 734 /* Check for the valid Upper non recovarable Value.*/ 735 if( (settingMask & UPPER_NON_RECOV_SPECIFIED) ) { 736 737 if( (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) && 738 (( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && ( setting1 <= val[5])) || 739 ( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && ( setting1 <= val[4]))) ) 740 { 741 lprintf(LOG_ERR, INVALID_THRESHOLD); 742 return -1; 743 } 744 } else if( (settingMask & UPPER_CRIT_SPECIFIED) ) { /* Check for the valid Upper critical Value.*/ 745 if( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && 746 (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&& ( setting1 >= val[6])) || 747 ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 <= val[4]))) ) 748 { 749 lprintf(LOG_ERR, INVALID_THRESHOLD); 750 return -1; 751 } 752 } else if( (settingMask & UPPER_NON_CRIT_SPECIFIED) ) { /* Check for the valid Upper non critical Value.*/ 753 if( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && 754 (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&&( setting1 >= val[6])) || 755 ((rsp->data[0] & UPPER_CRIT_SPECIFIED)&&( setting1 >= val[5])) || 756 ((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 <= val[1]))) ) 757 { 758 lprintf(LOG_ERR, INVALID_THRESHOLD); 759 return -1; 760 } 761 } else if( (settingMask & LOWER_NON_CRIT_SPECIFIED) ) { /* Check for the valid lower non critical Value.*/ 762 if( (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) && 763 (((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 <= val[2])) || 764 ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))|| 765 ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 >= val[4]))) ) 766 { 767 lprintf(LOG_ERR, INVALID_THRESHOLD); 768 return -1; 769 } 770 } else if( (settingMask & LOWER_CRIT_SPECIFIED) ) { /* Check for the valid lower critical Value.*/ 771 if( (rsp->data[0] & LOWER_CRIT_SPECIFIED) && 772 (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) || 773 ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))) ) 774 { 775 lprintf(LOG_ERR, INVALID_THRESHOLD); 776 return -1; 777 } 778 } else if( (settingMask & LOWER_NON_RECOV_SPECIFIED) ) { /* Check for the valid lower non recovarable Value.*/ 779 if( (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) && 780 (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) || 781 ((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 >= val[2]))) ) 782 { 783 lprintf(LOG_ERR, INVALID_THRESHOLD); 784 return -1; 785 } 786 } else { /* None of this Then Return with error messages.*/ 787 lprintf(LOG_ERR, INVALID_THRESHOLD); 788 return -1; 789 } 790 791 792 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 793 sdr->record.full->id_string, 794 val2str(settingMask, threshold_vals), setting1); 795 796 ret = __ipmi_sensor_set_threshold(intf, 797 sdr->record.common->keys. 798 sensor_num, settingMask, 799 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), 800 sdr->record.common->keys.owner_id, 801 sdr->record.common->keys.lun, 802 sdr->record.common->keys.channel); 803 } 804 805 return ret; 806 } 807 808 static int 809 ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv) 810 { 811 struct sdr_record_list *sdr; 812 int i, rc=0; 813 814 if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { 815 lprintf(LOG_NOTICE, "sensor reading <id> ... [id]"); 816 lprintf(LOG_NOTICE, " id : name of desired sensor"); 817 return -1; 818 } 819 820 for (i = 0; i < argc; i++) { 821 sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]); 822 if (sdr == NULL) { 823 lprintf(LOG_ERR, "Sensor \"%s\" not found!", 824 argv[i]); 825 rc = -1; 826 continue; 827 } 828 829 switch (sdr->type) { 830 case SDR_RECORD_TYPE_FULL_SENSOR: 831 case SDR_RECORD_TYPE_COMPACT_SENSOR: 832 { 833 struct sensor_reading *sr; 834 struct sdr_record_common_sensor *sensor = sdr->record.common; 835 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3); 836 837 if (sr == NULL) { 838 rc = -1; 839 continue; 840 } 841 842 if (!sr->full) 843 continue; 844 845 if (!sr->s_reading_valid) 846 continue; 847 848 if (!sr->s_has_analog_value) { 849 lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]); 850 continue; 851 } 852 if (csv_output) 853 printf("%s,%s\n", argv[i], sr->s_a_str); 854 else 855 printf("%-16s | %s\n", argv[i], sr->s_a_str); 856 857 break; 858 } 859 default: 860 continue; 861 } 862 } 863 864 return rc; 865 } 866 867 static int 868 ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv) 869 { 870 int i, v; 871 int rc = 0; 872 struct sdr_record_list *sdr; 873 874 if (argc < 1) { 875 lprintf(LOG_ERR, "Not enough parameters given."); 876 print_sensor_get_usage(); 877 return (-1); 878 } else if (strcmp(argv[0], "help") == 0) { 879 print_sensor_get_usage(); 880 return 0; 881 } 882 printf("Locating sensor record...\n"); 883 /* lookup by sensor name */ 884 for (i = 0; i < argc; i++) { 885 sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]); 886 if (sdr == NULL) { 887 lprintf(LOG_ERR, "Sensor data record \"%s\" not found!", 888 argv[i]); 889 rc = -1; 890 continue; 891 } 892 /* need to set verbose level to 1 */ 893 v = verbose; 894 verbose = 1; 895 switch (sdr->type) { 896 case SDR_RECORD_TYPE_FULL_SENSOR: 897 case SDR_RECORD_TYPE_COMPACT_SENSOR: 898 if (ipmi_sensor_print_fc(intf, 899 (struct sdr_record_common_sensor *) sdr->record.common, 900 sdr->type)) { 901 rc = -1; 902 } 903 break; 904 default: 905 if (ipmi_sdr_print_listentry(intf, sdr) < 0) { 906 rc = (-1); 907 } 908 break; 909 } 910 verbose = v; 911 sdr = NULL; 912 } 913 return rc; 914 } 915 916 int 917 ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv) 918 { 919 int rc = 0; 920 921 if (argc == 0) { 922 rc = ipmi_sensor_list(intf); 923 } else if (strncmp(argv[0], "help", 4) == 0) { 924 lprintf(LOG_NOTICE, "Sensor Commands: list thresh get reading"); 925 } else if (strncmp(argv[0], "list", 4) == 0) { 926 rc = ipmi_sensor_list(intf); 927 } else if (strncmp(argv[0], "thresh", 5) == 0) { 928 rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]); 929 } else if (strncmp(argv[0], "get", 3) == 0) { 930 rc = ipmi_sensor_get(intf, argc - 1, &argv[1]); 931 } else if (strncmp(argv[0], "reading", 7) == 0) { 932 rc = ipmi_sensor_get_reading(intf, argc - 1, &argv[1]); 933 } else { 934 lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]); 935 rc = -1; 936 } 937 938 return rc; 939 } 940 941 /* print_sensor_get_usage - print usage for # ipmitool sensor get NAC; 942 * 943 * @returns: void 944 */ 945 void 946 print_sensor_get_usage() 947 { 948 lprintf(LOG_NOTICE, "sensor get <id> ... [id]"); 949 lprintf(LOG_NOTICE, " id : name of desired sensor"); 950 } 951 952 /* print_sensor_thresh_set_usage - print usage for # ipmitool sensor thresh; 953 * 954 * @returns: void 955 */ 956 void 957 print_sensor_thresh_usage() 958 { 959 lprintf(LOG_NOTICE, 960 "sensor thresh <id> <threshold> <setting>"); 961 lprintf(LOG_NOTICE, 962 " id : name of the sensor for which threshold is to be set"); 963 lprintf(LOG_NOTICE, 964 " threshold : which threshold to set"); 965 lprintf(LOG_NOTICE, 966 " unr = upper non-recoverable"); 967 lprintf(LOG_NOTICE, 968 " ucr = upper critical"); 969 lprintf(LOG_NOTICE, 970 " unc = upper non-critical"); 971 lprintf(LOG_NOTICE, 972 " lnc = lower non-critical"); 973 lprintf(LOG_NOTICE, 974 " lcr = lower critical"); 975 lprintf(LOG_NOTICE, 976 " lnr = lower non-recoverable"); 977 lprintf(LOG_NOTICE, 978 " setting : the value to set the threshold to"); 979 lprintf(LOG_NOTICE, 980 ""); 981 lprintf(LOG_NOTICE, 982 "sensor thresh <id> lower <lnr> <lcr> <lnc>"); 983 lprintf(LOG_NOTICE, 984 " Set all lower thresholds at the same time"); 985 lprintf(LOG_NOTICE, 986 ""); 987 lprintf(LOG_NOTICE, 988 "sensor thresh <id> upper <unc> <ucr> <unr>"); 989 lprintf(LOG_NOTICE, 990 " Set all upper thresholds at the same time"); 991 lprintf(LOG_NOTICE, ""); 992 } 993