diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index b940899..789166e 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/include/ipmitool/ipmi_sdr.h @@ -726,6 +726,7 @@ struct ipmi_sdr_iterator { uint16_t reservation; int total; int next; + int use_built_in; }; struct sdr_record_list { @@ -791,7 +792,8 @@ static const char *sensor_type_desc[] __attribute__ ((unused)) = { "Management Subsystem Health", "Battery","Session Audit", "Version Change","FRU State" }; -struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf); +struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf, + int use_builtin); struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i); uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header, @@ -824,7 +826,8 @@ struct ipmi_rs *ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, struct ipmi_rs *ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor); const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type); -int ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id); +int ipmi_sdr_get_reservation(struct ipmi_intf *intf, int use_builtin, + uint16_t * reserve_id); int ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, struct sdr_record_full_sensor *sensor); diff --git a/ipmitool/include/ipmitool/ipmi_sdradd.h b/ipmitool/include/ipmitool/ipmi_sdradd.h new file mode 100644 index 0000000..9f481df --- /dev/null +++ b/ipmitool/include/ipmitool/ipmi_sdradd.h @@ -0,0 +1,43 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef IPMI_SDRADD_H +#define IPMI_SDRADD_H + +/* + * Methods to add SDRs to repository from built-in sensors or files + */ +int +ipmi_sdr_add_from_sensors(struct ipmi_intf *intf, int maxslot); + +int +ipmi_sdr_add_from_file(struct ipmi_intf *intf, const char *ifile); + +#endif /* IPMI_SDRADD_H */ diff --git a/ipmitool/lib/Makefile.am b/ipmitool/lib/Makefile.am index 769be44..e02985e 100644 --- a/ipmitool/lib/Makefile.am +++ b/ipmitool/lib/Makefile.am @@ -38,7 +38,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \ ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \ ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \ ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \ - ipmi_hpmfwupg.c + ipmi_hpmfwupg.c ipmi_sdradd.c libipmitool_la_LDFLAGS = -export-dynamic libipmitool_la_LIBADD = -lm diff --git a/ipmitool/lib/ipmi_fru.c b/ipmitool/lib/ipmi_fru.c index 8e5efbb..aa33c09 100644 --- a/ipmitool/lib/ipmi_fru.c +++ b/ipmitool/lib/ipmi_fru.c @@ -1904,7 +1904,7 @@ ipmi_fru_print_all(struct ipmi_intf * intf) rc = ipmi_fru_print(intf, NULL); printf("\n"); - if ((itr = ipmi_sdr_start(intf)) == NULL) + if ((itr = ipmi_sdr_start(intf, 0)) == NULL) return -1; while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 569294b..1cc5b80 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -613,7 +613,7 @@ ipmi_sdr_get_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr) sdr_rq.length = 5; /* only get the header */ memset(&req, 0, sizeof (req)); - if (use_built_in == 0) { + if (itr->use_built_in == 0) { req.msg.netfn = IPMI_NETFN_STORAGE; req.msg.cmd = GET_SDR; } else { @@ -638,8 +638,8 @@ ipmi_sdr_get_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr) sleep(rand() & 3); - if (ipmi_sdr_get_reservation(intf, &(itr->reservation)) - < 0) { + if (ipmi_sdr_get_reservation(intf, itr->use_built_in, + &(itr->reservation)) < 0) { lprintf(LOG_ERR, "Unable to renew SDR reservation"); return NULL; @@ -2351,7 +2351,7 @@ ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type) lprintf(LOG_DEBUG, "Querying SDR for sensor list"); if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return -1; @@ -2452,7 +2452,8 @@ ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type) * returns -1 on error */ int -ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id) +ipmi_sdr_get_reservation(struct ipmi_intf *intf, int use_builtin, + uint16_t * reserve_id) { struct ipmi_rs *rsp; struct ipmi_rq req; @@ -2460,7 +2461,7 @@ ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id) /* obtain reservation ID */ memset(&req, 0, sizeof (req)); - if (use_built_in == 0) { + if (use_builtin == 0) { req.msg.netfn = IPMI_NETFN_STORAGE; } else { req.msg.netfn = IPMI_NETFN_SE; @@ -2489,7 +2490,7 @@ ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id) * returns NULL on error */ struct ipmi_sdr_iterator * -ipmi_sdr_start(struct ipmi_intf *intf) +ipmi_sdr_start(struct ipmi_intf *intf, int use_builtin) { struct ipmi_sdr_iterator *itr; struct ipmi_rs *rsp; @@ -2516,11 +2517,15 @@ ipmi_sdr_start(struct ipmi_intf *intf) free(itr); return NULL; } + if (rsp->ccode > 0) { + free(itr); + return NULL; + } devid = (struct ipm_devid_rsp *) rsp->data; sdriana = (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id); - if (devid->device_revision & IPM_DEV_DEVICE_ID_SDR_MASK) { + if (!use_builtin && (devid->device_revision & IPM_DEV_DEVICE_ID_SDR_MASK)) { if ((devid->adtl_device_support & 0x02) == 0) { if ((devid->adtl_device_support & 0x01)) { lprintf(LOG_DEBUG, "Using Device SDRs\n"); @@ -2534,8 +2539,9 @@ ipmi_sdr_start(struct ipmi_intf *intf) lprintf(LOG_DEBUG, "Using SDR from Repository \n"); } } + itr->use_built_in = use_builtin ? 1 : use_built_in; /***********************/ - if (use_built_in == 0) { + if (itr->use_built_in == 0) { struct sdr_repo_info_rs sdr_info; /* get sdr repository info */ memset(&req, 0, sizeof (req)); @@ -2592,7 +2598,8 @@ ipmi_sdr_start(struct ipmi_intf *intf) lprintf(LOG_DEBUG, "SDR records : %d", sdr_info.count); } - if (ipmi_sdr_get_reservation(intf, &(itr->reservation)) < 0) { + if (ipmi_sdr_get_reservation(intf, itr->use_built_in, + &(itr->reservation)) < 0) { lprintf(LOG_ERR, "Unable to obtain SDR reservation"); free(itr); return NULL; @@ -2636,7 +2643,7 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, sdr_rq.offset = 0; memset(&req, 0, sizeof (req)); - if (use_built_in == 0) { + if (itr->use_built_in == 0) { req.msg.netfn = IPMI_NETFN_STORAGE; req.msg.cmd = GET_SDR; } else { @@ -2676,8 +2683,8 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, sleep(rand() & 3); - if (ipmi_sdr_get_reservation(intf, &(itr->reservation)) - < 0) { + if (ipmi_sdr_get_reservation(intf, itr->use_built_in, + &(itr->reservation)) < 0) { free(data); return NULL; } @@ -2832,7 +2839,7 @@ ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf, uint8_t num, uint8_t type) int found = 0; if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return NULL; @@ -2959,7 +2966,7 @@ ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf, uint8_t type) memset(head, 0, sizeof (struct sdr_record_list)); if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return NULL; @@ -3077,7 +3084,7 @@ ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf, struct entity_id *entity) memset(head, 0, sizeof (struct sdr_record_list)); if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return NULL; @@ -3261,7 +3268,7 @@ ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf, uint8_t type) memset(head, 0, sizeof (struct sdr_record_list)); if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return NULL; @@ -3362,7 +3369,7 @@ ipmi_sdr_find_sdr_byid(struct ipmi_intf *intf, char *id) idlen = strlen(id); if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return NULL; @@ -3671,7 +3678,7 @@ ipmi_sdr_list_cache(struct ipmi_intf *intf) struct sdr_get_rs *header; if (sdr_list_itr == NULL) { - sdr_list_itr = ipmi_sdr_start(intf); + sdr_list_itr = ipmi_sdr_start(intf, 0); if (sdr_list_itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return -1; @@ -3921,7 +3928,7 @@ ipmi_sdr_dump_bin(struct ipmi_intf *intf, const char *ofile) int rc = 0; /* open connection to SDR */ - itr = ipmi_sdr_start(intf); + itr = ipmi_sdr_start(intf, 0); if (itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return -1; @@ -4184,24 +4191,24 @@ ipmi_sdr_main(struct ipmi_intf *intf, int argc, char **argv) lprintf(LOG_ERR, "SDR Commands: list | elist [all|full|compact|event|mcloc|fru|generic]"); lprintf(LOG_ERR, - " all All SDR Records"); + " all All SDR Records"); lprintf(LOG_ERR, - " full Full Sensor Record"); + " full Full Sensor Record"); lprintf(LOG_ERR, - " compact Compact Sensor Record"); + " compact Compact Sensor Record"); lprintf(LOG_ERR, - " event Event-Only Sensor Record"); + " event Event-Only Sensor Record"); lprintf(LOG_ERR, - " mcloc Management Controller Locator Record"); + " mcloc Management Controller Locator Record"); lprintf(LOG_ERR, - " fru FRU Locator Record"); + " fru FRU Locator Record"); lprintf(LOG_ERR, - " generic Generic Device Locator Record"); + " generic Generic Device Locator Record"); lprintf(LOG_ERR, " type [sensor type]"); lprintf(LOG_ERR, - " list Get a list of available sensor types"); + " list Get a list of available sensor types"); lprintf(LOG_ERR, - " get Retrieve the state of a specified sensor"); + " get Retrieve the state of a specified sensor"); lprintf(LOG_ERR, " info"); lprintf(LOG_ERR, @@ -4212,6 +4219,11 @@ ipmi_sdr_main(struct ipmi_intf *intf, int argc, char **argv) lprintf(LOG_ERR, " dump "); lprintf(LOG_ERR, " Dump raw SDR data to a file"); + lprintf(LOG_ERR, " fill"); + lprintf(LOG_ERR, + " sensors Creates the SDR repository for the current configuration"); + lprintf(LOG_ERR, + " file Load SDR repository from a file"); } else if (strncmp(argv[0], "list", 4) == 0 || strncmp(argv[0], "elist", 5) == 0) { @@ -4260,6 +4272,21 @@ ipmi_sdr_main(struct ipmi_intf *intf, int argc, char **argv) lprintf(LOG_ERR, "usage: sdr dump "); else rc = ipmi_sdr_dump_bin(intf, argv[1]); + } else if (strncmp(argv[0], "fill", 3) == 0) { + if (argc <= 1) { + lprintf(LOG_ERR, "usage: sdr fill sensors"); + lprintf(LOG_ERR, "usage: sdr fill file "); + rc = -1; + } else if (strncmp(argv[1], "sensors", 7) == 0) { + rc = ipmi_sdr_add_from_sensors(intf, 21); + } else if (strncmp(argv[1], "file", 4) == 0) { + if (argc < 3) { + lprintf(LOG_ERR, "sdr fill: Missing filename"); + rc = -1; + } else { + rc = ipmi_sdr_add_from_file(intf, argv[2]); + } + } } else { lprintf(LOG_ERR, "Invalid SDR command: %s", argv[0]); rc = -1; diff --git a/ipmitool/lib/ipmi_sdradd.c b/ipmitool/lib/ipmi_sdradd.c new file mode 100644 index 0000000..5f2b501 --- /dev/null +++ b/ipmitool/lib/ipmi_sdradd.c @@ -0,0 +1,413 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * Functions to program the SDR repository, from built-in sensors or + * from sensors dumped in a binary file. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define ADD_PARTIAL_SDR 0x25 + +struct sdr_add_rq { + uint16_t reserve_id; /* reservation ID */ + uint16_t id; /* record ID */ + uint8_t offset; /* offset into SDR */ + uint8_t in_progress; /* 0=partial, 1=last */ +#define PARTIAL_ADD (0) +#define LAST_RECORD (1) + uint8_t data[1]; /* SDR record data */ +} __attribute__ ((packed)); + +static int sdr_max_write_len = 24; + +static int +partial_send(struct ipmi_intf *intf, struct ipmi_rq *req, uint16_t *id) +{ + struct ipmi_rs *rsp; + rsp = intf->sendrecv(intf, req); + if (rsp == NULL) { + return -1; + } + + if (rsp->ccode || rsp->data_len < 2) { + return -1; + } + + *id = rsp->data[0] + (rsp->data[1] << 8); + return 0; +} + +int +ipmi_sdr_add_record(struct ipmi_intf *intf, struct sdr_record_list *sdrr) +{ + struct ipmi_rq req; + struct sdr_add_rq *sdr_rq; + uint16_t reserve_id; + uint16_t id; + int i; + int len = sdrr->length; + int rc = 0; + + /* actually no SDR to program */ + if (len < 1 || !sdrr->raw) + return 0; + + if (ipmi_sdr_get_reservation(intf, 0, &reserve_id)) + return -1; + + sdr_rq = (struct sdr_add_rq *)malloc(sizeof(*sdr_rq) + sdr_max_write_len); + if (sdr_rq == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + return -1; + } + sdr_rq->reserve_id = reserve_id; + sdr_rq->in_progress = PARTIAL_ADD; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = ADD_PARTIAL_SDR; + req.msg.data = (uint8_t *) sdr_rq; + + /* header first */ + sdr_rq->id = 0; + sdr_rq->offset = 0; + sdr_rq->data[0] = sdrr->id & 0xFF; + sdr_rq->data[1] = (sdrr->id >> 8) & 0xFF; + sdr_rq->data[2] = sdrr->version; + sdr_rq->data[3] = sdrr->type; + sdr_rq->data[4] = sdrr->length; + req.msg.data_len = 5 + sizeof(*sdr_rq) - 1; + + if (partial_send(intf, &req, &id)) { + free(sdr_rq); + return -1; + } + + i = 0; + + /* sdr entry */ + while (i < len) { + int data_len = 0; + + if (len - i < sdr_max_write_len) { + /* last crunch */ + data_len = len - i; + sdr_rq->in_progress = LAST_RECORD; + } else { + data_len = sdr_max_write_len; + } + + sdr_rq->id = id; + sdr_rq->offset = i + 5; + memcpy(sdr_rq->data, sdrr->raw + i, data_len); + req.msg.data_len = data_len + sizeof(*sdr_rq) - 1; + + if ((rc = partial_send(intf, &req, &id)) != 0) { + break; + } + + i += data_len; + } + free(sdr_rq); + return rc; +} + +static int +ipmi_sdr_repo_clear(struct ipmi_intf *intf) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + uint8_t msg_data[8]; + uint16_t reserve_id; + int try; + + if (ipmi_sdr_get_reservation(intf, 0, &reserve_id)) + return -1; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = 0x27; // FIXME + req.msg.data = msg_data; + req.msg.data_len = 6; + + msg_data[0] = reserve_id & 0xFF; + msg_data[1] = reserve_id >> 8; + msg_data[2] = 'C'; + msg_data[3] = 'L'; + msg_data[4] = 'R'; + msg_data[5] = 0xAA; + + for (try = 0; try < 5; try++) { + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, "Unable to clear SDRR"); + return -1; + } + if (rsp->ccode > 0) { + lprintf(LOG_ERR, "Unable to clear SDRR: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + if ((rsp->data[0] & 1) == 1) { + printf("SDRR successfully erased\n"); + return 0; + } + printf("Wait for SDRR erasure completed...\n"); + msg_data[5] = 0; + sleep(1); + } + + /* if we are here we fed up trying erase */ + return -1; +} + + +struct sdrr_queue { + struct sdr_record_list *head; + struct sdr_record_list *tail; +}; + + +/* + * Fill the SDR repository from built-in sensors + * + */ + +/* + * Get all the SDR records stored in + */ +static int +sdrr_get_records(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr, + struct sdrr_queue *queue) +{ + struct sdr_get_rs *header; + + queue->head = NULL; + queue->tail = NULL; + + while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { + struct sdr_record_list *sdrr; + + sdrr = malloc(sizeof (struct sdr_record_list)); + if (sdrr == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + return -1; + } + memset(sdrr, 0, sizeof (struct sdr_record_list)); + sdrr->id = header->id; + sdrr->version = header->version; + sdrr->type = header->type; + sdrr->length = header->length; + sdrr->raw = ipmi_sdr_get_record(intf, header, itr); + + /* put in the record queue */ + if (queue->head == NULL) + queue->head = sdrr; + else + queue->tail->next = sdrr; + queue->tail = sdrr; + } + return 0; +} + +static int +sdr_copy_to_sdrr(struct ipmi_intf *intf, int use_builtin, + int from_addr, int to_addr) +{ + int rc; + struct sdrr_queue sdrr_queue; + struct ipmi_sdr_iterator *itr; + struct sdr_record_list *sdrr; + struct sdr_record_list *sdrr_next; + + /* generate list of records for this target */ + intf->target_addr = from_addr; + itr = ipmi_sdr_start(intf, use_builtin); + if (itr == 0) + return 0; + + printf("Load SDRs from 0x%x\n", from_addr); + rc = sdrr_get_records(intf, itr, &sdrr_queue); + ipmi_sdr_end(intf, itr); + + /* write the SDRs to the destination SDR Repository */ + intf->target_addr = to_addr; + for (sdrr = sdrr_queue.head; sdrr != NULL; sdrr = sdrr_next) { + sdrr_next = sdrr->next; + rc = ipmi_sdr_add_record(intf, sdrr); + if(rc < 0){ + lprintf(LOG_ERR, "Cannot add SDR ID 0x%04x to repository...", sdrr->id); + } + free(sdrr); + } + return rc; +} + +int +ipmi_sdr_add_from_sensors(struct ipmi_intf *intf, int maxslot) +{ + int i; + int rc = 0; + int slave_addr; + int myaddr = intf->target_addr; + + if (ipmi_sdr_repo_clear(intf)) { + lprintf(LOG_ERR, "Cannot erase SDRR. Give up."); + return -1; + } + + /* First fill the SDRR from local built-in sensors */ + rc = sdr_copy_to_sdrr(intf, 1, myaddr, myaddr); + + /* Now fill the SDRR with remote sensors */ + for (i = 0, slave_addr = 0xB0; i < maxslot; i++, slave_addr += 2) { + /* Hole in the PICMG 2.9 mapping */ + if (slave_addr == 0xC2) slave_addr += 2; + if(sdr_copy_to_sdrr(intf, 0, slave_addr, myaddr) < 0) + { + rc = -1; + } + } + return rc; +} + + +/* + * Fill the SDR repository from records stored in a binary file + * + */ + +static int +ipmi_sdr_read_records(const char *filename, struct sdrr_queue *queue) +{ + struct sdr_get_rs header; + int rc = 0; + int fd; + uint8_t binHdr[5]; + + queue->head = NULL; + queue->tail = NULL; + + if ((fd = open(filename, O_RDONLY)) < 0) { + return -1; + } + + while (read(fd, binHdr, 5) == 5) { + + struct sdr_record_list *sdrr; + + lprintf(LOG_DEBUG, "binHdr[0] (id[MSB]) = 0x%02x", binHdr[0]); + lprintf(LOG_DEBUG, "binHdr[1] (id[LSB]) = 0x%02x", binHdr[1]); + lprintf(LOG_DEBUG, "binHdr[2] (version) = 0x%02x", binHdr[2]); + lprintf(LOG_DEBUG, "binHdr[3] (type) = 0x%02x", binHdr[3]); + lprintf(LOG_DEBUG, "binHdr[4] (length) = 0x%02x", binHdr[4]); + + sdrr = malloc(sizeof(*sdrr)); + if (sdrr == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + rc = -1; + break; + } + sdrr->id = (binHdr[0] << 8) | binHdr[1]; + sdrr->version = binHdr[2]; + sdrr->type = binHdr[3]; + sdrr->length = binHdr[4]; + + if ((sdrr->raw = malloc(sdrr->length)) == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + free(sdrr); + rc = -1; + break; + } + + if (read(fd, sdrr->raw, sdrr->length) != sdrr->length) { + lprintf(LOG_ERR, "SDR from '%s' truncated", filename); + free(sdrr->raw); + free(sdrr); + rc = -1; + break; + } + + /* put in the record queue */ + if (queue->head == NULL) + queue->head = sdrr; + else + queue->tail->next = sdrr; + queue->tail = sdrr; + } + return rc; +} + +int +ipmi_sdr_add_from_file(struct ipmi_intf *intf, const char *ifile) +{ + int rc; + struct sdrr_queue sdrr_queue; + struct sdr_record_list *sdrr; + struct sdr_record_list *sdrr_next; + + /* read the SDR records from file */ + rc = ipmi_sdr_read_records(ifile, &sdrr_queue); + + if (ipmi_sdr_repo_clear(intf)) { + printf("Cannot erase SDRR. Give up.\n"); + /* FIXME: free sdr list */ + return -1; + } + + /* write the SDRs to the SDR Repository */ + for (sdrr = sdrr_queue.head; sdrr != NULL; sdrr = sdrr_next) { + sdrr_next = sdrr->next; + rc = ipmi_sdr_add_record(intf, sdrr); + if(rc < 0){ + lprintf(LOG_ERR, "Cannot add SDR ID 0x%04x to repository...", sdrr->id); + } + free(sdrr); + } + return rc; +} + diff --git a/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c index 0b2418c..9528626 100644 --- a/ipmitool/lib/ipmi_sensor.c +++ b/ipmitool/lib/ipmi_sensor.c @@ -496,7 +496,7 @@ ipmi_sensor_list(struct ipmi_intf *intf) lprintf(LOG_DEBUG, "Querying SDR for sensor list"); - itr = ipmi_sdr_start(intf); + itr = ipmi_sdr_start(intf, 0); if (itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return -1;