mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
new functions for iterating through sdr records
This commit is contained in:
parent
702627f6b3
commit
dd87b050b8
@ -99,6 +99,7 @@ struct sdr_get_rs {
|
|||||||
unsigned char version; /* SDR version (51h) */
|
unsigned char version; /* SDR version (51h) */
|
||||||
#define SDR_RECORD_TYPE_FULL_SENSOR 0x01
|
#define SDR_RECORD_TYPE_FULL_SENSOR 0x01
|
||||||
#define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02
|
#define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02
|
||||||
|
#define SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR 0x11
|
||||||
unsigned char type; /* record type */
|
unsigned char type; /* record type */
|
||||||
unsigned char length; /* remaining record bytes */
|
unsigned char length; /* remaining record bytes */
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
@ -292,6 +293,31 @@ struct sdr_record_full_sensor {
|
|||||||
unsigned char id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
|
unsigned char id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct sdr_record_fru_device_locator {
|
||||||
|
struct {
|
||||||
|
unsigned char __reserved1 : 1, dev_access_addr : 6;
|
||||||
|
unsigned char fru_device_id;
|
||||||
|
unsigned char private_bus : 3, access_lun : 2, __reserved3 : 2, logical_dev : 1;
|
||||||
|
unsigned char __reserved4 : 4, channel_num : 4;
|
||||||
|
} keys;
|
||||||
|
|
||||||
|
unsigned char __reserved;
|
||||||
|
unsigned char device_type;
|
||||||
|
unsigned char device_type_modifier;
|
||||||
|
unsigned char fru_entity_id;
|
||||||
|
unsigned char fru_entity_instance;
|
||||||
|
unsigned char oem;
|
||||||
|
unsigned char id_code;
|
||||||
|
unsigned char id_string[16];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct ipmi_sdr_iterator
|
||||||
|
{
|
||||||
|
unsigned short reservation;
|
||||||
|
int total;
|
||||||
|
int next;
|
||||||
|
};
|
||||||
|
|
||||||
/* unit description codes (IPMI v1.5 section 37.16) */
|
/* unit description codes (IPMI v1.5 section 37.16) */
|
||||||
#define UNIT_MAX 0x90
|
#define UNIT_MAX 0x90
|
||||||
static const char * unit_desc[] __attribute__((unused)) = {
|
static const char * unit_desc[] __attribute__((unused)) = {
|
||||||
@ -322,4 +348,9 @@ static const char * unit_desc[] __attribute__((unused)) = {
|
|||||||
"error", "correctable error", "uncorrectable error",
|
"error", "correctable error", "uncorrectable error",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ipmi_sdr_iterator * ipmi_sdr_start(struct ipmi_intf * intf);
|
||||||
|
struct sdr_get_rs * ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
|
||||||
|
unsigned char * ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * i);
|
||||||
|
void ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
|
||||||
|
|
||||||
#endif /* IPMI_SDR_H */
|
#endif /* IPMI_SDR_H */
|
||||||
|
@ -518,6 +518,132 @@ ipmi_sdr_print_sensors(struct ipmi_intf * intf, int do_unit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ipmi_sdr_iterator *
|
||||||
|
ipmi_sdr_start(struct ipmi_intf * intf)
|
||||||
|
{
|
||||||
|
struct ipmi_sdr_iterator * itr;
|
||||||
|
struct ipmi_rs * rsp;
|
||||||
|
struct ipmi_rq req;
|
||||||
|
struct sdr_repo_info_rs sdr_info;
|
||||||
|
struct sdr_reserve_repo_rs sdr_reserve;
|
||||||
|
struct sdr_get_rs * header;
|
||||||
|
|
||||||
|
if (!(itr = malloc (sizeof (struct ipmi_sdr_iterator))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* get sdr repository info */
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||||
|
req.msg.cmd = GET_SDR_REPO_INFO;
|
||||||
|
|
||||||
|
rsp = intf->sendrecv(intf, &req);
|
||||||
|
if (!rsp || !rsp->data_len)
|
||||||
|
{
|
||||||
|
free (itr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(&sdr_info, rsp->data, sizeof(sdr_info));
|
||||||
|
|
||||||
|
/* byte 1 is SDR version, should be 51h */
|
||||||
|
if (sdr_info.version != 0x51) {
|
||||||
|
printf("SDR repository version mismatch!\n");
|
||||||
|
free (itr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
itr->total = sdr_info.count;
|
||||||
|
if (verbose > 1) {
|
||||||
|
printf("SDR free space: %d\n", sdr_info.free);
|
||||||
|
printf("SDR records: %d\n", sdr_info.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* obtain reservation ID */
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||||
|
req.msg.cmd = GET_SDR_RESERVE_REPO;
|
||||||
|
rsp = intf->sendrecv(intf, &req);
|
||||||
|
if (!rsp || !rsp->data_len)
|
||||||
|
{
|
||||||
|
free (itr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(&sdr_reserve, rsp->data, sizeof(sdr_reserve));
|
||||||
|
itr->reservation = sdr_reserve.reserve_id;
|
||||||
|
if (verbose > 1)
|
||||||
|
printf("SDR reserveration ID %04x\n", sdr_reserve.reserve_id);
|
||||||
|
|
||||||
|
itr->next = 0;
|
||||||
|
|
||||||
|
return itr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sdr_get_rs *
|
||||||
|
ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr)
|
||||||
|
{
|
||||||
|
struct sdr_get_rs *header;
|
||||||
|
|
||||||
|
if (itr->next >= itr->total)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(header = ipmi_sdr_get_header(intf, itr->reservation, itr->next)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
itr->next = header->next;
|
||||||
|
|
||||||
|
return (header);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * itr)
|
||||||
|
{
|
||||||
|
struct ipmi_rq req;
|
||||||
|
struct ipmi_rs * rsp;
|
||||||
|
struct sdr_get_rq sdr_rq;
|
||||||
|
struct sdr_record_compact_sensor * sensor;
|
||||||
|
unsigned char * data;
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
|
||||||
|
if (!(data = malloc (header->length)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset(&sdr_rq, 0, sizeof(sdr_rq));
|
||||||
|
sdr_rq.reserve_id = itr->reservation;
|
||||||
|
sdr_rq.id = header->id;
|
||||||
|
sdr_rq.offset = 0;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||||
|
req.msg.cmd = GET_SDR;
|
||||||
|
req.msg.data = (unsigned char *)&sdr_rq;
|
||||||
|
req.msg.data_len = sizeof(sdr_rq);
|
||||||
|
|
||||||
|
len = header->length;
|
||||||
|
|
||||||
|
/* read SDR record with partial (30 byte) reads
|
||||||
|
* because a full read (0xff) exceeds the maximum
|
||||||
|
* transport buffer size. (completion code 0xca)
|
||||||
|
*/
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
for (i=0; i<len; i+=GET_SDR_MAX_LEN) {
|
||||||
|
sdr_rq.length = (len-i < GET_SDR_MAX_LEN) ? len-i : GET_SDR_MAX_LEN;
|
||||||
|
sdr_rq.offset = i+5; /* 5 header bytes */
|
||||||
|
if (verbose > 1)
|
||||||
|
printf("getting %d bytes from SDR at offset %d\n",
|
||||||
|
sdr_rq.length, sdr_rq.offset);
|
||||||
|
rsp = intf->sendrecv(intf, &req);
|
||||||
|
if (rsp && rsp->data)
|
||||||
|
memcpy(data+i, rsp->data+2, sdr_rq.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr)
|
||||||
|
{
|
||||||
|
free (itr);
|
||||||
|
}
|
||||||
|
|
||||||
int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
|
int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||||
{
|
{
|
||||||
if (!argc)
|
if (!argc)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user