add sdr_cache function, fix Get SDR Header to handle cancelled reservation

This commit is contained in:
Duncan Laurie 2005-04-20 20:44:59 +00:00
parent 392454c646
commit 6052a2b57a
2 changed files with 146 additions and 30 deletions

View File

@ -79,6 +79,15 @@ int32_t utos(uint32_t val, int bits);
#define SDR_SENSOR_STAT_HI_CR (1<<4)
#define SDR_SENSOR_STAT_HI_NR (1<<5)
#define READING_UNAVAILABLE 0x20
#define SCANNING_DISABLED 0x40
#define EVENTS_DISABLED 0x80
#define GET_SENSOR_READING 0x2d
#define GET_SENSOR_FACTORS 0x23
#define GET_SENSOR_THRES 0x27
#define GET_SENSOR_TYPE 0x2f
struct sdr_repo_info_rs {
uint8_t version; /* SDR version (51h) */
uint16_t count; /* number of records */
@ -624,5 +633,7 @@ struct sdr_record_list * ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char *
void ipmi_sdr_list_empty(struct ipmi_intf * intf);
int ipmi_sdr_print_info(struct ipmi_intf * intf);
void ipmi_sdr_print_discrete_state(uint8_t sensor_type, uint8_t event_type, uint8_t state);
char * ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier);
int ipmi_sdr_list_cache(struct ipmi_intf * intf);
#endif /* IPMI_SDR_H */

View File

@ -55,15 +55,6 @@
# include <config.h>
#endif
#define READING_UNAVAILABLE 0x20
#define SCANNING_DISABLED 0x40
#define EVENTS_DISABLED 0x80
#define GET_SENSOR_READING 0x2d
#define GET_SENSOR_FACTORS 0x23
#define GET_SENSOR_THRES 0x27
#define GET_SENSOR_TYPE 0x2f
extern int verbose;
static int sdr_max_read_len = GET_SDR_ENTIRE_RECORD;
@ -89,6 +80,33 @@ utos(uint32_t val, int bits)
return val;
}
char *
ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier)
{
static char unitstr[16];
memset(unitstr, 0, sizeof(unitstr));
switch (type) {
case 2:
snprintf(unitstr, sizeof(unitstr), "%s * %s",
unit_desc[base],
unit_desc[modifier]);
break;
case 1:
snprintf(unitstr, sizeof(unitstr), "%s/%s",
unit_desc[base],
unit_desc[modifier]);
break;
case 0:
default:
snprintf(unitstr, sizeof(unitstr), "%s",
unit_desc[base]);
break;
}
return unitstr;
}
/* sdr_convert_sensor_reading - convert raw sensor reading
*
* @sensor: sensor record
@ -270,24 +288,23 @@ ipmi_sdr_get_status(uint8_t stat)
/* ipmi_sdr_get_header - retreive SDR record header
*
* @intf: ipmi interface
* @reserve_id: repository reservation id
* @record_id: sensor record id to retrieve
* @itr: sdr iterator
*
* returns pointer to static sensor retrieval struct
* returns NULL on error
*/
static struct sdr_get_rs *
ipmi_sdr_get_header(struct ipmi_intf * intf, uint16_t reserve_id,
uint16_t record_id)
ipmi_sdr_get_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr)
{
struct ipmi_rq req;
struct ipmi_rs * rsp;
struct sdr_get_rq sdr_rq;
static struct sdr_get_rs sdr_rs;
int try = 0;
memset(&sdr_rq, 0, sizeof(sdr_rq));
sdr_rq.reserve_id = reserve_id;
sdr_rq.id = record_id;
sdr_rq.reserve_id = itr->reservation;
sdr_rq.id = itr->next;
sdr_rq.offset = 0;
sdr_rq.length = 5; /* only get the header */
@ -297,24 +314,42 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, uint16_t reserve_id,
req.msg.data = (uint8_t *)&sdr_rq;
req.msg.data_len = sizeof(sdr_rq);
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get SDR %04x command failed", record_id);
return NULL;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get SDR %04x command failed: %s",
record_id, val2str(rsp->ccode, completion_code_vals));
return NULL;
for (try=0; try<5; try++) {
sdr_rq.reserve_id = itr->reservation;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get SDR %04x command failed", itr->next);
return NULL;
}
else if (rsp->ccode == 0xc5) {
/* lost reservation */
lprintf(LOG_DEBUG, "SDR reserveration %04x cancelled. "
"Sleeping a bit and retrying...", itr->reservation);
sleep(rand() & 3);
if (ipmi_sdr_get_reservation(intf, &(itr->reservation)) < 0) {
lprintf(LOG_ERR, "Unable to renew SDR reservation");
return NULL;
}
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get SDR %04x command failed: %s",
itr->next, val2str(rsp->ccode, completion_code_vals));
return NULL;
}
else {
break;
}
}
lprintf(LOG_DEBUG, "SDR record ID : 0x%04x", record_id);
lprintf(LOG_DEBUG, "SDR record ID : 0x%04x", itr->next);
memcpy(&sdr_rs, rsp->data, sizeof(sdr_rs));
if (sdr_rs.length == 0) {
lprintf(LOG_ERR, "SDR record id 0x%04x: invalid length %d",
record_id, sdr_rs.length);
itr->next, sdr_rs.length);
return NULL;
}
@ -326,10 +361,10 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, uint16_t reserve_id,
* completion code CBh = "Requested Sensor, data, or record
* not present"
*/
if (sdr_rs.id != record_id) {
if (sdr_rs.id != itr->next) {
lprintf(LOG_DEBUG, "SDR record id mismatch: 0x%04x",
sdr_rs.id);
sdr_rs.id = record_id;
sdr_rs.id = itr->next;
}
lprintf(LOG_DEBUG, "SDR record type : 0x%02x", sdr_rs.type);
@ -356,7 +391,7 @@ ipmi_sdr_get_next_header(struct ipmi_intf * intf,
if (itr->next == 0xffff)
return NULL;
header = ipmi_sdr_get_header(intf, itr->reservation, itr->next);
header = ipmi_sdr_get_header(intf, itr);
if (header == NULL)
return NULL;
@ -1480,7 +1515,7 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
continue;
case 0xc5:
/* lost reservation */
lprintf(LOG_DEBUG, "SDR reserveration canceled. "
lprintf(LOG_DEBUG, "SDR reserveration cancelled. "
"Sleeping a bit and retrying...");
sleep(rand() & 3);
@ -1977,6 +2012,76 @@ ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id)
}
/* ipmi_sdr_list_cache - generate SDR cache for fast lookup
*
* @intf: ipmi interface
*
* returns pointer to SDR list
* returns NULL on error
*/
int
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);
if (sdr_list_itr == NULL) {
lprintf(LOG_ERR, "Unable to open SDR for reading");
return -1;
}
}
while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
uint8_t * rec;
struct sdr_record_list * sdrr;
sdrr = malloc(sizeof(struct sdr_record_list));
if (sdrr == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
break;
}
memset(sdrr, 0, sizeof(struct sdr_record_list));
sdrr->id = header->id;
sdrr->type = header->type;
rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
if (rec == NULL)
continue;
switch (header->type) {
case SDR_RECORD_TYPE_FULL_SENSOR:
sdrr->record.full = (struct sdr_record_full_sensor *)rec;
break;
case SDR_RECORD_TYPE_COMPACT_SENSOR:
sdrr->record.compact = (struct sdr_record_compact_sensor *)rec;
break;
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
sdrr->record.eventonly = (struct sdr_record_eventonly_sensor *)rec;
break;
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
sdrr->record.fruloc = (struct sdr_record_fru_locator *)rec;
break;
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
sdrr->record.mcloc = (struct sdr_record_mc_locator *)rec;
break;
default:
free(rec);
continue;
}
/* add to global record liset */
if (sdr_list_head == NULL)
sdr_list_head = sdrr;
else
sdr_list_tail->next = sdrr;
sdr_list_tail = sdrr;
}
return 0;
}
/*
* ipmi_sdr_get_info
*