From fc29d57ffc2a749df13c0882a2503a5a756e8ae0 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 18 Dec 2003 22:42:32 +0000 Subject: [PATCH] - rework "sdr list" command to take additional argument specifying what type of SDR records to dispaly - add support for MC locator records - better support for compact records --- ipmitool/include/ipmitool/ipmi_sdr.h | 30 ++- ipmitool/lib/ipmi_sdr.c | 293 +++++++++++++++++++-------- 2 files changed, 238 insertions(+), 85 deletions(-) diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index b34862c..08f0684 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/include/ipmitool/ipmi_sdr.h @@ -97,9 +97,16 @@ struct sdr_get_rs { unsigned short next; /* next record id */ unsigned short id; /* record ID */ unsigned char version; /* SDR version (51h) */ -#define SDR_RECORD_TYPE_FULL_SENSOR 0x01 -#define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02 -#define SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR 0x11 +#define SDR_RECORD_TYPE_FULL_SENSOR 0x01 +#define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02 +#define SDR_RECORD_TYPE_ENTITY_ASSOC 0x08 +#define SDR_RECORD_TYPE_DEVICE_ENTITY_ASSOC 0x09 +#define SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR 0x10 +#define SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR 0x11 +#define SDR_RECORD_TYPE_MC_DEVICE_LOCATOR 0x12 +#define SDR_RECORD_TYPE_MC_CONFIRMATION 0x13 +#define SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO 0x14 +#define SDR_RECORD_TYPE_OEM 0xc0 unsigned char type; /* record type */ unsigned char length; /* remaining record bytes */ } __attribute__ ((packed)); @@ -253,9 +260,7 @@ struct sdr_record_full_sensor { } unit; unsigned char linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */ - unsigned short mtol; /* M, tolerance */ - unsigned long bacc; /* accuracy, B, Bexp, Rexp */ struct { @@ -311,6 +316,21 @@ struct sdr_record_fru_device_locator { unsigned char id_string[16]; } __attribute__ ((packed)); +struct sdr_record_mc_locator { + unsigned char __reserved1 : 1, dev_slave_addr : 7; + unsigned char channel_num : 4, __reserved2 : 4; + unsigned char global_init : 4, __reserved3 : 1, pwr_state_notif : 3; + unsigned char dev_support; + unsigned char __reserved4[3]; + struct { + unsigned char id; + unsigned char instance; + } entity; + unsigned char oem; + unsigned char id_code; + unsigned char id_string[16]; +} __attribute__ ((packed)); + struct ipmi_sdr_iterator { unsigned short reservation; diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index e1c2b51..88197bc 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -39,6 +39,7 @@ #include #include +#include #include extern int verbose; @@ -135,7 +136,7 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, unsigned short reserve_id, unsigned } if (verbose > 1) - printf("SDR Record ID : 0x%04x\n", record_id); + printf("SDR record ID : 0x%04x\n", record_id); memcpy(&sdr_rs, rsp->data, sizeof(sdr_rs)); @@ -146,7 +147,7 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, unsigned short reserve_id, unsigned } if (verbose > 1) { - printf("SDR record type : %d\n", sdr_rs.type); + printf("SDR record type : 0x%02x\n", sdr_rs.type); printf("SDR record next : %d\n", sdr_rs.next); printf("SDR record bytes: %d\n", sdr_rs.length); } @@ -170,78 +171,13 @@ ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr return header; } -static void -ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, - struct sdr_record_compact_sensor * sensor) +static inline int get_offset(unsigned char x) { - struct ipmi_rs * rsp; - char desc[17]; - char state[20]; - - if (!sensor) - return; - - memset(desc, 0, sizeof(desc)); - memcpy(desc, sensor->id_string, 16); - - rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); - if (!rsp || rsp->ccode) { - printf("Unable to get sensor %x reading\n", sensor->keys.sensor_num); - return; - } - - if (verbose) { - printf("Sensor ID : %s (0x%x)\n", - sensor->id_code ? desc : NULL, sensor->keys.sensor_num); - printf("Entity ID : %d.%d (%s)\n", - sensor->entity.id, sensor->entity.instance, - val2str(sensor->entity.id, entity_id_vals)); - if (verbose > 1) { - printf("Sensor Type Code : 0x%02x\n", sensor->sensor.type); - printf("Event Type Code : 0x%02x\n", sensor->event_type); - printbuf(rsp->data, rsp->data_len, "COMPACT SENSOR READING"); - } - } - - if (!(rsp->data[1] & 0x80)) - return; /* sensor scanning disabled */ - - /* TODO: handle this using SEL decode functions */ - memset(state, 0, sizeof(state)); - if (sensor->event_type == 0x6f) { - if (verbose) - printf("State : "); - else { - if (csv_output) - printf("%s,", sensor->id_code ? desc : NULL); - else - printf("%-16s | ", sensor->id_code ? desc : NULL); - } - - switch (sensor->sensor.type) { - case 0x07: /* processor */ - if (rsp->data[2] & 0x80) - printf("Present "); - else - printf("Not Present "); - break; - case 0x21: /* slot/connector */ - if (rsp->data[2] & 0x04) - printf("Installed "); - else - printf("Not Installed "); - break; - default: - printf("Unknown "); - } - - if (!verbose) - printf("| ok"); - printf("\n"); - } - - if (verbose) - printf("\n"); + int i; + for (i=0; i<8; i++) + if (x>>i == 1) + return i; + return 0; } static void @@ -387,7 +323,161 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, } static void -ipmi_sdr_print_sensors(struct ipmi_intf * intf) +ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, + struct sdr_record_compact_sensor * sensor) +{ + struct ipmi_rs * rsp; + char desc[17]; + unsigned char typ, off; + struct ipmi_event_sensor_types *evt; + + if (!sensor) + return; + + memset(desc, 0, sizeof(desc)); + memcpy(desc, sensor->id_string, 16); + + rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); + if (!rsp || rsp->ccode) { + printf("Unable to get sensor %x reading\n", sensor->keys.sensor_num); + return; + } + + if (!(rsp->data[1] & 0x80)) + return; /* sensor scanning disabled */ + + if (verbose) { + printf("Sensor ID : %s (0x%x)\n", + sensor->id_code ? desc : NULL, sensor->keys.sensor_num); + printf("Entity ID : %d.%d (%s)\n", + sensor->entity.id, sensor->entity.instance, + val2str(sensor->entity.id, entity_id_vals)); + if (verbose > 1) { + printf("Sensor Type Code : 0x%02x\n", sensor->sensor.type); + printf("Event Type Code : 0x%02x\n", sensor->event_type); + printbuf(rsp->data, rsp->data_len, "COMPACT SENSOR READING"); + } + + + off = get_offset(rsp->data[2]); + if (off) { + if (sensor->event_type == 0x6f) { + evt = sensor_specific_types; + typ = sensor->sensor.type; + } else { + evt = generic_event_types; + typ = sensor->event_type; + } + while (evt->type) { + if (evt->code == typ && evt->offset == off) + printf("State : %s\n", evt->desc); + evt++; + } + } + printf("\n"); + } + else { + char * state; + + switch (sensor->sensor.type) { + case 0x07: /* processor */ + if (rsp->data[2] & 0x80) + state = strdup("Present "); + else + state = strdup("Not Present "); + break; + case 0x21: /* slot/connector */ + if (rsp->data[2] & 0x04) + state = strdup("Installed "); + else + state = strdup("Not Installed "); + break; + default: + return; + } + + if (csv_output) + printf("%s,", sensor->id_code ? desc : NULL); + else + printf("%-16s | ", sensor->id_code ? desc : NULL); + + printf("%s | ok\n", state); + free(state); + } +} + +static void +ipmi_sdr_print_mc_locator(struct ipmi_intf * intf, + struct sdr_record_mc_locator * mc) +{ + char desc[17]; + + memset(desc, 0, sizeof(desc)); + memcpy(desc, mc->id_string, 16); + + if (!verbose) { + if (csv_output) + printf("%s,", mc->id_code ? desc : NULL); + else + printf("%-16s | ", mc->id_code ? desc : NULL); + + printf("%s MC @ %02Xh %s | ok\n", + (mc->pwr_state_notif & 0x1) ? "Static" : "Dynamic", + mc->dev_slave_addr, + (mc->pwr_state_notif & 0x1) ? " " : ""); + return; + } + + printf("Device ID : %s\n", mc->id_string); + printf("Entity ID : %d.%d (%s)\n", + mc->entity.id, mc->entity.instance, + val2str(mc->entity.id, entity_id_vals)); + + printf("Device Slave Address : %02Xh\n", mc->dev_slave_addr); + printf("Channel Number : %01Xh\n", mc->channel_num); + + printf("ACPI System P/S Notif : %sRequired\n", + (mc->pwr_state_notif & 0x4) ? "" : "Not "); + printf("ACPI Device P/S Notif : %sRequired\n", + (mc->pwr_state_notif & 0x2) ? "" : "Not "); + printf("Controller Presence : %s\n", + (mc->pwr_state_notif & 0x1) ? "Static" : "Dynamic"); + printf("Logs Init Agent Errors : %s\n", + (mc->global_init & 0x8) ? "Yes" : "No"); + + printf("Event Message Gen : "); + if (!(mc->global_init & 0x3)) + printf("Enable\n"); + else if ((mc->global_init & 0x3) == 0x1) + printf("Disable\n"); + else if ((mc->global_init & 0x3) == 0x2) + printf("Do Not Init Controller\n"); + else + printf("Reserved\n"); + + printf("Device Capabilities\n"); + printf(" Chassis Device : %s\n", + (mc->dev_support & 0x80) ? "Yes" : "No"); + printf(" Bridge : %s\n", + (mc->dev_support & 0x40) ? "Yes" : "No"); + printf(" IPMB Event Generator : %s\n", + (mc->dev_support & 0x20) ? "Yes" : "No"); + printf(" IPMB Event Receiver : %s\n", + (mc->dev_support & 0x10) ? "Yes" : "No"); + printf(" FRU Inventory Device : %s\n", + (mc->dev_support & 0x08) ? "Yes" : "No"); + printf(" SEL Device : %s\n", + (mc->dev_support & 0x04) ? "Yes" : "No"); + printf(" SDR Repository : %s\n", + (mc->dev_support & 0x02) ? "Yes" : "No"); + printf(" Sensor Device : %s\n", + (mc->dev_support & 0x01) ? "Yes" : "No"); + + printf("\n"); +} + +static void +ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type) { struct sdr_get_rs * header; struct ipmi_sdr_iterator * itr; @@ -402,9 +492,15 @@ ipmi_sdr_print_sensors(struct ipmi_intf * intf) } while (header = ipmi_sdr_get_next_header(intf, itr)) { - unsigned char * rec = ipmi_sdr_get_record(intf, header, itr); + unsigned char * rec; + + if (type != header->type && type != 0xff) + continue; + + rec = ipmi_sdr_get_record(intf, header, itr); if (!rec) continue; + switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: ipmi_sdr_print_sensor_full(intf, @@ -414,6 +510,24 @@ ipmi_sdr_print_sensors(struct ipmi_intf * intf) ipmi_sdr_print_sensor_compact(intf, (struct sdr_record_compact_sensor *) rec); break; + case SDR_RECORD_TYPE_ENTITY_ASSOC: + break; + case SDR_RECORD_TYPE_DEVICE_ENTITY_ASSOC: + break; + case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR: + break; + case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR: + break; + case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR: + ipmi_sdr_print_mc_locator(intf, + (struct sdr_record_mc_locator *) rec); + break; + case SDR_RECORD_TYPE_MC_CONFIRMATION: + break; + case SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO: + break; + case SDR_RECORD_TYPE_OEM: + break; } free(rec); } @@ -531,11 +645,30 @@ ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr) int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv) { if (!argc) - ipmi_sdr_print_sensors(intf); - else if (!strncmp(argv[0], "help", 4)) - printf("SDR Commands: list\n"); - else if (!strncmp(argv[0], "list", 4)) - ipmi_sdr_print_sensors(intf); + ipmi_sdr_print_sdr(intf, 0xff); + else if (!strncmp(argv[0], "help", 4)) { + printf("SDR Commands: list [all|full|compact|mcloc]\n"); + printf(" all All SDR Records\n"); + printf(" full Full Sensor Record\n"); + printf(" compact Compact Sensor Record\n"); + printf(" mcloc Management Controller Locator Record\n"); + } + else if (!strncmp(argv[0], "list", 4)) { + if (argc > 1) { + if (!strncmp(argv[1], "all", 3)) + ipmi_sdr_print_sdr(intf, 0xff); + else if (!strncmp(argv[1], "full", 4)) + ipmi_sdr_print_sdr(intf, SDR_RECORD_TYPE_FULL_SENSOR); + else if (!strncmp(argv[1], "compact", 7)) + ipmi_sdr_print_sdr(intf, SDR_RECORD_TYPE_COMPACT_SENSOR); + else if (!strncmp(argv[1], "mcloc", 5)) + ipmi_sdr_print_sdr(intf, SDR_RECORD_TYPE_MC_DEVICE_LOCATOR); + else + printf("usage: sdr list [all|full|compact|mcloc]\n"); + } else { + ipmi_sdr_print_sdr(intf, 0xff); + } + } else printf("Invalid SDR command: %s\n", argv[0]); return 0;