mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
handle errors gracefully,
check values before malloc, add external function for entity association lookups
This commit is contained in:
parent
7723fb41b3
commit
a87957ac7f
@ -62,20 +62,22 @@ static char * get_fru_area_str(unsigned char * data, int * offset)
|
|||||||
|
|
||||||
k = ((data[off] & 0xC0) >> 6); /* bits 6,7 contain format */
|
k = ((data[off] & 0xC0) >> 6); /* bits 6,7 contain format */
|
||||||
len = data[off++];
|
len = data[off++];
|
||||||
len &= 0x3f; /* bits 0:5 contain length */
|
len &= 0x3f; /* bits 0:5 contain length */
|
||||||
|
|
||||||
switch(k) {
|
switch(k) {
|
||||||
case 0: /* 0: binary/unspecified */
|
case 0: /* 0: binary/unspecified */
|
||||||
size = (len*2); /* (hex dump -> 2x length) */
|
size = (len*2); /* (hex dump -> 2x length) */
|
||||||
break;
|
break;
|
||||||
case 2: /* 2: 6-bit ASCII */
|
case 2: /* 2: 6-bit ASCII */
|
||||||
size = ((((len+2)*4)/3) & ~3);/* (4 chars per group of 1-3 bytes) */
|
size = ((((len+2)*4)/3) & ~3);/* (4 chars per group of 1-3 bytes) */
|
||||||
break;
|
break;
|
||||||
case 3: /* 3: 8-bit ASCII */
|
case 3: /* 3: 8-bit ASCII */
|
||||||
case 1: /* 1: BCD plus */
|
case 1: /* 1: BCD plus */
|
||||||
size = len; /* (no length adjustment) */
|
size = len; /* (no length adjustment) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size < 1)
|
||||||
|
return NULL;
|
||||||
str = malloc(size+1);
|
str = malloc(size+1);
|
||||||
if (!str)
|
if (!str)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -85,7 +87,7 @@ static char * get_fru_area_str(unsigned char * data, int * offset)
|
|||||||
else {
|
else {
|
||||||
switch(k) {
|
switch(k) {
|
||||||
case 0:
|
case 0:
|
||||||
strcpy(str, buf2str(&data[off], len));
|
strncpy(str, buf2str(&data[off], len));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@ -140,9 +142,20 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, unsigned char id,
|
|||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
unsigned char msg_data[4];
|
unsigned char msg_data[4];
|
||||||
|
|
||||||
finish = offset + length;
|
if (offset > fru->size) {
|
||||||
if (finish > fru->size)
|
if (verbose)
|
||||||
|
printf("Read FRU Area offset incorrect: %d > %d\n",
|
||||||
|
offset, fru->size);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish = offset + length;
|
||||||
|
if (finish > fru->size) {
|
||||||
|
finish = fru->size;
|
||||||
|
if (verbose)
|
||||||
|
printf("Read FRU Area length %d too large, adjusting to %d\n",
|
||||||
|
offset + length, finish - offset);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_STORAGE;
|
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||||
@ -155,7 +168,7 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, unsigned char id,
|
|||||||
do {
|
do {
|
||||||
tmp = fru->access ? off >> 1 : off;
|
tmp = fru->access ? off >> 1 : off;
|
||||||
msg_data[0] = id;
|
msg_data[0] = id;
|
||||||
msg_data[1] = (unsigned char)tmp;
|
msg_data[1] = (unsigned char)(tmp & 0xff);
|
||||||
msg_data[2] = (unsigned char)(tmp >> 8);
|
msg_data[2] = (unsigned char)(tmp >> 8);
|
||||||
tmp = finish - off;
|
tmp = finish - off;
|
||||||
if (tmp > fru_data_rqst_size)
|
if (tmp > fru_data_rqst_size)
|
||||||
@ -164,12 +177,23 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, unsigned char id,
|
|||||||
msg_data[3] = (unsigned char)tmp;
|
msg_data[3] = (unsigned char)tmp;
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (!rsp)
|
if (!rsp) {
|
||||||
|
if (verbose)
|
||||||
|
printf("FRU Read failed\n");
|
||||||
break;
|
break;
|
||||||
if ((rsp->ccode==0xc7 || rsp->ccode==0xc8) && --fru_data_rqst_size > 8)
|
}
|
||||||
continue;
|
if (rsp->ccode) {
|
||||||
if (rsp->ccode)
|
if (verbose)
|
||||||
|
printf("FRU Read failed: %s\n",
|
||||||
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
|
if ((rsp->ccode==0xc7 || rsp->ccode==0xc8) && --fru_data_rqst_size > 8) {
|
||||||
|
if (verbose)
|
||||||
|
printf("Retrying FRU read with request size %d\n",
|
||||||
|
fru_data_rqst_size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = fru->access ? rsp->data[0] << 1 : rsp->data[0];
|
tmp = fru->access ? rsp->data[0] << 1 : rsp->data[0];
|
||||||
memcpy((frubuf + off), rsp->data + 1, tmp);
|
memcpy((frubuf + off), rsp->data + 1, tmp);
|
||||||
@ -179,7 +203,7 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, unsigned char id,
|
|||||||
return (off >= finish);
|
return (off >= finish);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
static void __ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
||||||
{
|
{
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
@ -212,13 +236,13 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
req.msg.data_len = 1;
|
req.msg.data_len = 1;
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (!rsp)
|
if (!rsp) {
|
||||||
|
printf(" Device not present (No Response)\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if(rsp->ccode)
|
if(rsp->ccode) {
|
||||||
{
|
printf(" Device not present (%s)\n",
|
||||||
if (rsp->ccode == 0xc3)
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
printf (" Timeout accessing FRU info. (Device not present?)\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fru.size = (rsp->data[1] << 8) | rsp->data[0];
|
fru.size = (rsp->data[1] << 8) | rsp->data[0];
|
||||||
@ -227,8 +251,10 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf("fru.size = %d bytes (accessed by %s)\n",
|
printf("fru.size = %d bytes (accessed by %s)\n",
|
||||||
fru.size, fru.access ? "words" : "bytes");
|
fru.size, fru.access ? "words" : "bytes");
|
||||||
if (!fru.size)
|
if (!fru.size) {
|
||||||
|
printf(" FRU size is zero!\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
msg_data[0] = id;
|
msg_data[0] = id;
|
||||||
msg_data[1] = 0;
|
msg_data[1] = 0;
|
||||||
@ -246,10 +272,13 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
if (!rsp)
|
if (!rsp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(rsp->ccode)
|
if (!rsp) {
|
||||||
{
|
printf(" Device not present (No Response)\n");
|
||||||
if (rsp->ccode == 0xc3)
|
return;
|
||||||
printf (" Timeout while reading FRU data. (Device not present?)\n");
|
}
|
||||||
|
if(rsp->ccode) {
|
||||||
|
printf(" Device not present (%s)\n",
|
||||||
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +289,7 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
|
|
||||||
if (header.version != 0x01)
|
if (header.version != 0x01)
|
||||||
{
|
{
|
||||||
printf (" Unknown FRU header version %02x.\n", header.version);
|
printf (" Unknown FRU header version %02x.\n", header.version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +308,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
printf("fru.header.offset.multi: 0x%x\n", area_offsets[OFF_MULTI]);
|
printf("fru.header.offset.multi: 0x%x\n", area_offsets[OFF_MULTI]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fru.size < 1)
|
||||||
|
return;
|
||||||
fru_data = malloc(fru.size+1);
|
fru_data = malloc(fru.size+1);
|
||||||
if (!fru_data)
|
if (!fru_data)
|
||||||
return;
|
return;
|
||||||
@ -302,16 +333,18 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
chassis.part = get_fru_area_str(fru_data, &i);
|
chassis.part = get_fru_area_str(fru_data, &i);
|
||||||
chassis.serial = get_fru_area_str(fru_data, &i);
|
chassis.serial = get_fru_area_str(fru_data, &i);
|
||||||
|
|
||||||
printf(" Chassis Type : %s\n", chassis_type_desc[chassis.type]);
|
printf(" Chassis Type : %s\n", chassis_type_desc[chassis.type]);
|
||||||
printf(" Chassis Part : %s\n", chassis.part);
|
if (strlen(chassis.part) > 0)
|
||||||
printf(" Chassis Serial : %s\n", chassis.serial);
|
printf(" Chassis Part Number : %s\n", chassis.part);
|
||||||
|
if (strlen(chassis.serial) > 0)
|
||||||
|
printf(" Chassis Serial : %s\n", chassis.serial);
|
||||||
|
|
||||||
while (fru_data[i] != 0xc1 && i < area_offsets[OFF_CHASSIS] + chassis.area_len)
|
while (fru_data[i] != 0xc1 && i < area_offsets[OFF_CHASSIS] + chassis.area_len)
|
||||||
{
|
{
|
||||||
char *extra;
|
char *extra;
|
||||||
|
|
||||||
extra = get_fru_area_str(fru_data, &i);
|
extra = get_fru_area_str(fru_data, &i);
|
||||||
if (extra [0]) printf(" Chassis Extra : %s\n", extra);
|
if (extra [0]) printf(" Chassis Extra : %s\n", extra);
|
||||||
free(extra);
|
free(extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,20 +373,24 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
board.part = get_fru_area_str(fru_data, &i);
|
board.part = get_fru_area_str(fru_data, &i);
|
||||||
board.fru = get_fru_area_str(fru_data, &i);
|
board.fru = get_fru_area_str(fru_data, &i);
|
||||||
|
|
||||||
printf(" Board Mfg : %s\n", board.mfg);
|
if (strlen(board.mfg) > 0)
|
||||||
printf(" Board Product : %s\n", board.prod);
|
printf(" Board Manufacturer : %s\n", board.mfg);
|
||||||
printf(" Board Serial : %s\n", board.serial);
|
if (strlen(board.prod) > 0)
|
||||||
printf(" Board Part : %s\n", board.part);
|
printf(" Board Product : %s\n", board.prod);
|
||||||
|
if (strlen(board.serial) > 0)
|
||||||
|
printf(" Board Serial : %s\n", board.serial);
|
||||||
|
if (strlen(board.part) > 0)
|
||||||
|
printf(" Board Part Number : %s\n", board.part);
|
||||||
|
|
||||||
if (verbose > 0)
|
if ((verbose > 0) && (strlen(board.fru) > 0))
|
||||||
printf(" Board FRU ID : %s\n", board.fru);
|
printf(" Board FRU ID : %s\n", board.fru);
|
||||||
|
|
||||||
while (fru_data[i] != 0xc1 && i < area_offsets[OFF_BOARD] + board.area_len)
|
while (fru_data[i] != 0xc1 && i < area_offsets[OFF_BOARD] + board.area_len)
|
||||||
{
|
{
|
||||||
char *extra;
|
char *extra;
|
||||||
|
|
||||||
extra = get_fru_area_str(fru_data, &i);
|
extra = get_fru_area_str(fru_data, &i);
|
||||||
if (extra [0]) printf(" Board Extra : %s\n", extra);
|
if (extra [0]) printf(" Board Extra : %s\n", extra);
|
||||||
free(extra);
|
free(extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,22 +423,28 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
product.asset = get_fru_area_str(fru_data, &i);
|
product.asset = get_fru_area_str(fru_data, &i);
|
||||||
product.fru = get_fru_area_str(fru_data, &i);
|
product.fru = get_fru_area_str(fru_data, &i);
|
||||||
|
|
||||||
printf(" Product Mfg : %s\n", product.mfg);
|
if (strlen(product.mfg) > 0)
|
||||||
printf(" Product Name : %s\n", product.name);
|
printf(" Product Manufacturer : %s\n", product.mfg);
|
||||||
printf(" Product Part : %s\n", product.part);
|
if (strlen(product.name) > 0)
|
||||||
printf(" Product Version : %s\n", product.version);
|
printf(" Product Name : %s\n", product.name);
|
||||||
printf(" Product Serial : %s\n", product.serial);
|
if (strlen(product.part) > 0)
|
||||||
printf(" Product Asset : %s\n", product.asset);
|
printf(" Product Part Number : %s\n", product.part);
|
||||||
|
if (strlen(product.version) > 0)
|
||||||
|
printf(" Product Version : %s\n", product.version);
|
||||||
|
if (strlen(product.serial) > 0)
|
||||||
|
printf(" Product Serial : %s\n", product.serial);
|
||||||
|
if (strlen(product.asset) > 0)
|
||||||
|
printf(" Product Asset Tag : %s\n", product.asset);
|
||||||
|
|
||||||
if (verbose > 0)
|
if ((verbose > 0) && (strlen(product.fru) > 0))
|
||||||
printf(" Product FRU ID : %s\n", product.fru);
|
printf(" Product FRU ID : %s\n", product.fru);
|
||||||
|
|
||||||
while (fru_data[i] != 0xc1 && i < area_offsets[OFF_PRODUCT] + product.area_len)
|
while (fru_data[i] != 0xc1 && i < area_offsets[OFF_PRODUCT] + product.area_len)
|
||||||
{
|
{
|
||||||
char *extra;
|
char *extra;
|
||||||
|
|
||||||
extra = get_fru_area_str(fru_data, &i);
|
extra = get_fru_area_str(fru_data, &i);
|
||||||
if (extra [0]) printf(" Product Extra : %s\n", extra);
|
if (extra [0]) printf(" Product Extra : %s\n", extra);
|
||||||
free(extra);
|
free(extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +486,7 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
if (read_fru_area(intf, &fru, id, last_off, len, fru_data) > 0)
|
if (read_fru_area(intf, &fru, id, last_off, len, fru_data) > 0)
|
||||||
last_off += len;
|
last_off += len;
|
||||||
else {
|
else {
|
||||||
printf("ERROR: reading FRU data\n");
|
printf("ERROR: reading FRU multirecord data\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,16 +509,16 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
peak_hold_up_time = (ps->peak_cap_ht & 0xf000) >> 12;
|
peak_hold_up_time = (ps->peak_cap_ht & 0xf000) >> 12;
|
||||||
peak_capacity = ps->peak_cap_ht & 0x0fff;
|
peak_capacity = ps->peak_cap_ht & 0x0fff;
|
||||||
|
|
||||||
printf (" Power Supply Record\n");
|
printf (" Power Supply Record\n");
|
||||||
printf (" Capacity : %d W\n", ps->capacity);
|
printf (" Capacity : %d W\n", ps->capacity);
|
||||||
printf (" Peak VA : %d VA\n", ps->peak_va);
|
printf (" Peak VA : %d VA\n", ps->peak_va);
|
||||||
printf (" Inrush Current : %d A\n", ps->inrush_current);
|
printf (" Inrush Current : %d A\n", ps->inrush_current);
|
||||||
printf (" Inrush Interval : %d ms\n", ps->inrush_interval);
|
printf (" Inrush Interval : %d ms\n", ps->inrush_interval);
|
||||||
printf (" Input Voltage Range 1 : %d-%d V\n", ps->lowend_input1 / 100, ps->highend_input1 / 100);
|
printf (" Input Voltage Range 1 : %d-%d V\n", ps->lowend_input1 / 100, ps->highend_input1 / 100);
|
||||||
printf (" Input Voltage Range 2 : %d-%d V\n", ps->lowend_input2 / 100, ps->highend_input2 / 100);
|
printf (" Input Voltage Range 2 : %d-%d V\n", ps->lowend_input2 / 100, ps->highend_input2 / 100);
|
||||||
printf (" Input Frequency Range : %d-%d Hz\n", ps->lowend_freq, ps->highend_freq);
|
printf (" Input Frequency Range : %d-%d Hz\n", ps->lowend_freq, ps->highend_freq);
|
||||||
printf (" A/C Dropout Tolerance : %d ms\n", ps->dropout_tolerance);
|
printf (" A/C Dropout Tolerance : %d ms\n", ps->dropout_tolerance);
|
||||||
printf (" Flags : %s%s%s%s%s\n",
|
printf (" Flags : %s%s%s%s%s\n",
|
||||||
ps->predictive_fail ? "'Predictive fail' " : "",
|
ps->predictive_fail ? "'Predictive fail' " : "",
|
||||||
ps->pfc ? "'Power factor correction' " : "",
|
ps->pfc ? "'Power factor correction' " : "",
|
||||||
ps->autoswitch ? "'Autoswitch voltage' " : "",
|
ps->autoswitch ? "'Autoswitch voltage' " : "",
|
||||||
@ -483,16 +526,16 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
ps->predictive_fail ? ps->rps_threshold ?
|
ps->predictive_fail ? ps->rps_threshold ?
|
||||||
ps->tach ? "'Two pulses per rotation'" : "'One pulse per rotation'" :
|
ps->tach ? "'Two pulses per rotation'" : "'One pulse per rotation'" :
|
||||||
ps->tach ? "'Failure on pin de-assertion'" : "'Failure on pin assertion'" : "");
|
ps->tach ? "'Failure on pin de-assertion'" : "'Failure on pin assertion'" : "");
|
||||||
printf (" Peak capacity : %d W\n", peak_capacity);
|
printf (" Peak capacity : %d W\n", peak_capacity);
|
||||||
printf (" Peak capacity holdup : %d s\n", peak_hold_up_time);
|
printf (" Peak capacity holdup : %d s\n", peak_hold_up_time);
|
||||||
if (ps->combined_capacity == 0)
|
if (ps->combined_capacity == 0)
|
||||||
printf (" Combined capacity : not specified\n");
|
printf (" Combined capacity : not specified\n");
|
||||||
else
|
else
|
||||||
printf (" Combined capacity : %d W (%s and %s)\n", ps->combined_capacity,
|
printf (" Combined capacity : %d W (%s and %s)\n", ps->combined_capacity,
|
||||||
combined_voltage_desc [ps->combined_voltage1],
|
combined_voltage_desc [ps->combined_voltage1],
|
||||||
combined_voltage_desc [ps->combined_voltage2]);
|
combined_voltage_desc [ps->combined_voltage2]);
|
||||||
if (ps->predictive_fail)
|
if (ps->predictive_fail)
|
||||||
printf (" Fan lower threshold : %d RPS\n", ps->rps_threshold);
|
printf (" Fan lower threshold : %d RPS\n", ps->rps_threshold);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -508,15 +551,15 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
dc->max_current = BSWAP_16(dc->max_current);
|
dc->max_current = BSWAP_16(dc->max_current);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf (" DC Output Record\n");
|
printf (" DC Output Record\n");
|
||||||
printf (" Output Number : %d\n", dc->output_number);
|
printf (" Output Number : %d\n", dc->output_number);
|
||||||
printf (" Standby power : %s\n", dc->standby ? "Yes" : "No");
|
printf (" Standby power : %s\n", dc->standby ? "Yes" : "No");
|
||||||
printf (" Nominal voltage : %.2f V\n", (double) dc->nominal_voltage / 100);
|
printf (" Nominal voltage : %.2f V\n", (double) dc->nominal_voltage / 100);
|
||||||
printf (" Max negative deviation : %.2f V\n", (double) dc->max_neg_dev / 100);
|
printf (" Max negative deviation : %.2f V\n", (double) dc->max_neg_dev / 100);
|
||||||
printf (" Max positive deviation : %.2f V\n", (double) dc->max_pos_dev / 100);
|
printf (" Max positive deviation : %.2f V\n", (double) dc->max_pos_dev / 100);
|
||||||
printf (" Ripple and noise pk-pk : %d mV\n", dc->ripple_and_noise);
|
printf (" Ripple and noise pk-pk : %d mV\n", dc->ripple_and_noise);
|
||||||
printf (" Minimum current draw : %.3f A\n", (double) dc->min_current / 1000);
|
printf (" Minimum current draw : %.3f A\n", (double) dc->min_current / 1000);
|
||||||
printf (" Maximum current draw : %.3f A\n", (double) dc->max_current / 1000);
|
printf (" Maximum current draw : %.3f A\n", (double) dc->max_current / 1000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRU_RECORD_TYPE_DC_LOAD:
|
case FRU_RECORD_TYPE_DC_LOAD:
|
||||||
@ -531,14 +574,14 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
dl->max_current = BSWAP_16(dl->max_current);
|
dl->max_current = BSWAP_16(dl->max_current);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
printf (" DC Load Record\n");
|
printf (" DC Load Record\n");
|
||||||
printf (" Output Number : %d\n", dl->output_number);
|
printf (" Output Number : %d\n", dl->output_number);
|
||||||
printf (" Nominal voltage : %.2f V\n", (double) dl->nominal_voltage / 100);
|
printf (" Nominal voltage : %.2f V\n", (double) dl->nominal_voltage / 100);
|
||||||
printf (" Min voltage allowed : %.2f V\n", (double) dl->min_voltage / 100);
|
printf (" Min voltage allowed : %.2f V\n", (double) dl->min_voltage / 100);
|
||||||
printf (" Max voltage allowed : %.2f V\n", (double) dl->max_voltage / 100);
|
printf (" Max voltage allowed : %.2f V\n", (double) dl->max_voltage / 100);
|
||||||
printf (" Ripple and noise pk-pk : %d mV\n", dl->ripple_and_noise);
|
printf (" Ripple and noise pk-pk : %d mV\n", dl->ripple_and_noise);
|
||||||
printf (" Minimum current load : %.3f A\n", (double) dl->min_current / 1000);
|
printf (" Minimum current load : %.3f A\n", (double) dl->min_current / 1000);
|
||||||
printf (" Maximum current load : %.3f A\n", (double) dl->max_current / 1000);
|
printf (" Maximum current load : %.3f A\n", (double) dl->max_current / 1000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i += h->len + sizeof (struct fru_multirec_header);
|
i += h->len + sizeof (struct fru_multirec_header);
|
||||||
@ -548,16 +591,66 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
|||||||
free(fru_data);
|
free(fru_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
|
||||||
|
{
|
||||||
|
char desc[17];
|
||||||
|
unsigned char sav_addr;
|
||||||
|
|
||||||
|
if (!fru) {
|
||||||
|
__ipmi_fru_print(intf, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fru->dev_type != 0x10 &&
|
||||||
|
(fru->dev_type_modifier != 0x02 ||
|
||||||
|
fru->dev_type < 0x08 || fru->dev_type > 0x0f))
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(desc, 0, sizeof(desc));
|
||||||
|
memcpy(desc, fru->id_string, fru->id_code & 0x01f);
|
||||||
|
desc[fru->id_code & 0x01f] = 0;
|
||||||
|
printf("FRU Device Description : %s (ID %d)\n", desc, fru->device_id);
|
||||||
|
|
||||||
|
switch (fru->dev_type_modifier) {
|
||||||
|
case 0x00:
|
||||||
|
case 0x02:
|
||||||
|
sav_addr = intf->target_addr;
|
||||||
|
intf->target_addr = fru->dev_slave_addr;
|
||||||
|
|
||||||
|
if (intf->target_addr == IPMI_BMC_SLAVE_ADDR &&
|
||||||
|
fru->device_id == 0)
|
||||||
|
printf(" (Builtin FRU device)\n");
|
||||||
|
else
|
||||||
|
__ipmi_fru_print(intf, fru->device_id);
|
||||||
|
|
||||||
|
intf->target_addr = sav_addr;
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
ipmi_spd_print(intf, fru->device_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (verbose)
|
||||||
|
printf(" Unsupported device 0x%02x "
|
||||||
|
"type 0x%02x with modifier 0x%02x\n",
|
||||||
|
fru->device_id, fru->dev_type,
|
||||||
|
fru->dev_type_modifier);
|
||||||
|
else
|
||||||
|
printf(" Unsupported device\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void ipmi_fru_print_all(struct ipmi_intf * intf)
|
static void ipmi_fru_print_all(struct ipmi_intf * intf)
|
||||||
{
|
{
|
||||||
struct ipmi_sdr_iterator * itr;
|
struct ipmi_sdr_iterator * itr;
|
||||||
struct sdr_get_rs * header;
|
struct sdr_get_rs * header;
|
||||||
struct sdr_record_fru_device_locator * fru;
|
struct sdr_record_fru_locator * fru;
|
||||||
char desc[17];
|
char desc[17];
|
||||||
unsigned char sav_addr;
|
unsigned char sav_addr;
|
||||||
|
|
||||||
printf ("Builtin FRU device\n");
|
printf("FRU Device Description : Builtin FRU Device (ID 0)\n");
|
||||||
ipmi_fru_print(intf, 0); /* TODO: Figure out if FRU device 0 may show up in SDR records. */
|
ipmi_fru_print(intf, NULL); /* TODO: Figure out if FRU device 0 may show up in SDR records. */
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
if (!(itr = ipmi_sdr_start(intf)))
|
if (!(itr = ipmi_sdr_start(intf)))
|
||||||
return;
|
return;
|
||||||
@ -567,48 +660,11 @@ static void ipmi_fru_print_all(struct ipmi_intf * intf)
|
|||||||
if (header->type != SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR)
|
if (header->type != SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fru = (struct sdr_record_fru_device_locator *) ipmi_sdr_get_record(intf, header, itr);
|
fru = (struct sdr_record_fru_locator *)ipmi_sdr_get_record(intf, header, itr);
|
||||||
if (!fru)
|
if (!fru)
|
||||||
continue;
|
continue;
|
||||||
if (fru->device_type != 0x10
|
ipmi_fru_print(intf, fru);
|
||||||
&& (fru->device_type_modifier != 0x02
|
free(fru);
|
||||||
|| fru->device_type < 0x08 || fru->device_type > 0x0f))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
memset(desc, 0, sizeof(desc));
|
|
||||||
memcpy(desc, fru->id_string, fru->id_code & 0x01f);
|
|
||||||
desc[fru->id_code & 0x01f] = 0;
|
|
||||||
printf("\nFRU Device Description: %s Device ID: %d\n", desc, fru->keys.fru_device_id);
|
|
||||||
|
|
||||||
switch (fru->device_type_modifier) {
|
|
||||||
case 0x00:
|
|
||||||
case 0x02:
|
|
||||||
sav_addr = intf->target_addr;
|
|
||||||
intf->target_addr = ((fru->keys.dev_access_addr << 1)
|
|
||||||
| (fru->keys.__reserved2 << 7));
|
|
||||||
|
|
||||||
if (intf->target_addr == IPMI_BMC_SLAVE_ADDR
|
|
||||||
&& fru->keys.fru_device_id == 0)
|
|
||||||
printf(" (Builtin FRU device)\n");
|
|
||||||
else
|
|
||||||
ipmi_fru_print(intf, fru->keys.fru_device_id);
|
|
||||||
|
|
||||||
intf->target_addr = sav_addr;
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
ipmi_spd_print(intf, fru->keys.fru_device_id);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (verbose)
|
|
||||||
printf(" Unsupported device 0x%02x "
|
|
||||||
"type 0x%02x with modifier 0x%02x\n",
|
|
||||||
fru->keys.fru_device_id, fru->device_type,
|
|
||||||
fru->device_type_modifier);
|
|
||||||
else
|
|
||||||
printf(" Unsupported device\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
free (fru);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ipmi_sdr_end(intf, itr);
|
ipmi_sdr_end(intf, itr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user