From 533582e9e34d8947fd77dcd062dae1d7d5b69486 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 28 Jun 2006 20:58:08 +0000 Subject: [PATCH] add remote spd printing --- ipmitool/include/ipmitool/ipmi_fru.h | 2 + ipmitool/include/ipmitool/ipmi_raw.h | 1 + ipmitool/lib/dimm_spd.c | 114 +++++++++++++++------------ ipmitool/lib/ipmi_fru.c | 3 +- ipmitool/lib/ipmi_raw.c | 42 +++++++++- ipmitool/src/ipmitool.c | 1 + 6 files changed, 109 insertions(+), 54 deletions(-) diff --git a/ipmitool/include/ipmitool/ipmi_fru.h b/ipmitool/include/ipmitool/ipmi_fru.h index 2ac2f38..e8a48f7 100644 --- a/ipmitool/include/ipmitool/ipmi_fru.h +++ b/ipmitool/include/ipmitool/ipmi_fru.h @@ -314,5 +314,7 @@ static const char *chassis_type_desc[] __attribute__ ((unused)) = { int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv); int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru); +int ipmi_spd_print(uint8_t *data, int len); +int ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id); #endif /* IPMI_FRU_H */ diff --git a/ipmitool/include/ipmitool/ipmi_raw.h b/ipmitool/include/ipmitool/ipmi_raw.h index 7ed9189..f4364f3 100644 --- a/ipmitool/include/ipmitool/ipmi_raw.h +++ b/ipmitool/include/ipmitool/ipmi_raw.h @@ -39,5 +39,6 @@ int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv); struct ipmi_rs * ipmi_master_write_read(struct ipmi_intf * intf, uint8_t bus, uint8_t addr, uint8_t * wdata, uint8_t wsize, uint8_t rsize); int ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv); +int ipmi_rawspd_main(struct ipmi_intf * intf, int argc, char ** argv); #endif /* IPMI_RAW_H */ diff --git a/ipmitool/lib/dimm_spd.c b/ipmitool/lib/dimm_spd.c index e94f210..1f3c5f6 100644 --- a/ipmitool/lib/dimm_spd.c +++ b/ipmitool/lib/dimm_spd.c @@ -669,13 +669,74 @@ const struct valstr jedec_id5_vals[] = { }; int -ipmi_spd_print(struct ipmi_intf * intf, uint8_t id) +ipmi_spd_print(uint8_t *spd_data, int len) +{ + int size; + + if (len < 92) + return -1; /* we need first 91 bytes to do our thing */ + + size = spd_data[5] * (spd_data[31] << 2); + printf(" Memory Size : %d MB\n", size); + printf(" Memory Type : %s\n", + val2str(spd_data[2], spd_memtype_vals)); + printf(" Voltage Intf : %s\n", + val2str(spd_data[8], spd_voltage_vals)); + printf(" Error Detect/Cor : %s\n", + val2str(spd_data[11], spd_config_vals)); + + /* handle jedec table bank continuation values */ + printf(" Manufacturer : "); + if (spd_data[64] != 0x7f) + printf("%s\n", + val2str(spd_data[64], jedec_id1_vals)); + else { + if (spd_data[65] != 0x7f) + printf("%s\n", + val2str(spd_data[65], jedec_id2_vals)); + else { + if (spd_data[66] != 0x7f) + printf("%s\n", + val2str(spd_data[66], jedec_id3_vals)); + else { + if (spd_data[67] != 0x7f) + printf("%s\n", + val2str(spd_data[67], + jedec_id4_vals)); + else + printf("%s\n", + val2str(spd_data[68], + jedec_id5_vals)); + } + } + } + + if (spd_data[73]) { + char part[19]; + memcpy(part, spd_data+73, 18); + part[18] = 0; + printf(" Part Number : %s\n", part); + } + + printf(" Serial Number : %02x%02x%02x%02x\n", + spd_data[95], spd_data[96], spd_data[97], spd_data[98]); + + if (verbose) { + printf("\n"); + printbuf(spd_data, len, "SPD DATA"); + } + + return 0; +} + +int +ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id) { struct ipmi_rs * rsp; struct ipmi_rq req; struct fru_info fru; uint8_t spd_data[256], msg_data[4]; - int len, offset, size; + int len, offset; msg_data[0] = id; @@ -742,53 +803,8 @@ ipmi_spd_print(struct ipmi_intf * intf, uint8_t id) offset += len; } while (offset < fru.size); - if (verbose > 1) - printbuf(spd_data, offset, "SPD DATA"); - - if (offset < 92) - return -1; /* we need first 91 bytes to do our thing */ - - size = spd_data[5] * (spd_data[31] << 2); - printf(" Memory Size : %d MB\n", size); - printf(" Memory Type : %s\n", - val2str(spd_data[2], spd_memtype_vals)); - printf(" Voltage Intf : %s\n", - val2str(spd_data[8], spd_voltage_vals)); - printf(" Error Detect/Cor : %s\n", - val2str(spd_data[11], spd_config_vals)); - - /* handle jedec table bank continuation values */ - printf(" Manufacturer : "); - if (spd_data[64] != 0x7f) - printf("%s\n", - val2str(spd_data[64], jedec_id1_vals)); - else { - if (spd_data[65] != 0x7f) - printf("%s\n", - val2str(spd_data[65], jedec_id2_vals)); - else { - if (spd_data[66] != 0x7f) - printf("%s\n", - val2str(spd_data[66], jedec_id3_vals)); - else { - if (spd_data[67] != 0x7f) - printf("%s\n", - val2str(spd_data[67], - jedec_id4_vals)); - else - printf("%s\n", - val2str(spd_data[68], - jedec_id5_vals)); - } - } - } - - if (spd_data[73]) { - char part[19]; - memcpy(part, spd_data+73, 18); - part[18] = 0; - printf(" Part Number : %s\n", part); - } + /* now print spd info */ + ipmi_spd_print(spd_data, offset); return 0; } diff --git a/ipmitool/lib/ipmi_fru.c b/ipmitool/lib/ipmi_fru.c index e3b2c4b..b27592b 100644 --- a/ipmitool/lib/ipmi_fru.c +++ b/ipmitool/lib/ipmi_fru.c @@ -58,7 +58,6 @@ static char fileName[512]; extern int verbose; -extern int ipmi_spd_print(struct ipmi_intf * intf, uint8_t id); static void ipmi_fru_read_to_bin(struct ipmi_intf * intf, char * pFileName, uint8_t fruId); static void ipmi_fru_write_from_bin(struct ipmi_intf * intf, char * pFileName, uint8_t fruId); @@ -1251,7 +1250,7 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru) intf->target_addr = save_addr; break; case 0x01: - rc = ipmi_spd_print(intf, fru->device_id); + rc = ipmi_spd_print_fru(intf, fru->device_id); break; default: if (verbose) diff --git a/ipmitool/lib/ipmi_raw.c b/ipmitool/lib/ipmi_raw.c index 6651340..748f3d2 100644 --- a/ipmitool/lib/ipmi_raw.c +++ b/ipmitool/lib/ipmi_raw.c @@ -39,9 +39,10 @@ #include #include #include +#include #include -#define IPMI_I2C_MASTER_MAX_SIZE 0x40 +#define IPMI_I2C_MASTER_MAX_SIZE 0x40 /* 64 bytes */ /* ipmi_master_write_read - Perform I2C write/read transactions * @@ -126,6 +127,42 @@ ipmi_master_write_read(struct ipmi_intf * intf, uint8_t bus, uint8_t addr, return rsp; } +#define RAW_SPD_SIZE 256 + +int +ipmi_rawspd_main(struct ipmi_intf * intf, int argc, char ** argv) +{ + struct ipmi_rs *rsp; + uint8_t i2cbus = 0; + uint8_t i2caddr = 0; + uint8_t spd_data[RAW_SPD_SIZE]; + int i; + + memset(spd_data, 0, RAW_SPD_SIZE); + + if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { + lprintf(LOG_NOTICE, "usage: spd "); + return 0; + } + + i2cbus = (uint8_t)strtoul(argv[0], NULL, 0); + i2caddr = (uint8_t)strtoul(argv[1], NULL, 0); + + for (i = 0; i < RAW_SPD_SIZE; i+= IPMI_I2C_MASTER_MAX_SIZE) { + rsp = ipmi_master_write_read(intf, i2cbus, i2caddr, + (uint8_t *)&i, 1, IPMI_I2C_MASTER_MAX_SIZE); + if (rsp == NULL) { + lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read"); + return -1; + } + + memcpy(spd_data+i, rsp->data, IPMI_I2C_MASTER_MAX_SIZE); + } + + ipmi_spd_print(spd_data, i); + return 0; +} + static void rawi2c_usage(void) { lprintf(LOG_NOTICE, "usage: i2c [bus=public|# [chan=#]] [write data]"); @@ -271,7 +308,7 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) memset(data, 0, sizeof(data)); memset(&req, 0, sizeof(req)); req.msg.netfn = netfn; - req.msg.lun = lun; + req.msg.lun = lun; req.msg.cmd = cmd; req.msg.data = data; @@ -316,4 +353,3 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) return 0; } - diff --git a/ipmitool/src/ipmitool.c b/ipmitool/src/ipmitool.c index 6e3d09e..bfe84df 100644 --- a/ipmitool/src/ipmitool.c +++ b/ipmitool/src/ipmitool.c @@ -77,6 +77,7 @@ int verbose = 0; struct ipmi_cmd ipmitool_cmd_list[] = { { ipmi_raw_main, "raw", "Send a RAW IPMI request and print response" }, { ipmi_rawi2c_main, "i2c", "Send an I2C Master Write-Read command and print response" }, + { ipmi_rawspd_main, "spd", "Print SPD info from remote I2C device" }, { ipmi_lanp_main, "lan", "Configure LAN Channels" }, { ipmi_chassis_main, "chassis", "Get chassis status and set power state" }, { ipmi_power_main, "power", "Shortcut to chassis power commands" },