static int ipmi_sensor_list(struct ipmi_intf *intf) { struct sdr_get_rs *header; struct ipmi_sdr_iterator *itr; int rc = 0; lprintf(LOG_DEBUG, "Querying SDR for sensor list"); itr = ipmi_sdr_start(intf, 0); if (itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return -1; } while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { uint8_t *rec; rec = ipmi_sdr_get_record(intf, header, itr); if (rec == NULL) { lprintf(LOG_DEBUG, "rec == NULL"); continue; } switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR: ipmi_sensor_print_fc(intf, (struct sdr_record_common_sensor *) rec, header->type); break; } free(rec); rec = NULL; /* fix for CR6604909: */ /* mask failure of individual reads in sensor list command */ /* rc = (r == 0) ? rc : r; */ } ipmi_sdr_end(intf, itr); 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 <queue> */ 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); (void)ipmi_sdr_print_name_from_rawentry(intf, sdrr->id, sdrr->type,sdrr->raw); /* 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; /* initialize iterator */ 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); sdrr = NULL; } 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 */ if( maxslot != 0 ) { 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; }