convert FRU to be big-endian aware

this is messy because packed structures are not portable...
This commit is contained in:
Duncan Laurie 2004-01-27 20:10:55 +00:00
parent 122f422da7
commit e7c7d7d2e9
3 changed files with 92 additions and 10 deletions

View File

@ -40,6 +40,10 @@
#include <stdint.h>
#include <ipmitool/ipmi.h>
#if HAVE_CONFIG_H
# include <config.h>
#endif
#define GET_FRU_INFO 0x10
#define GET_FRU_DATA 0x11
#define SET_FRU_DATA 0x12
@ -125,7 +129,12 @@ struct fru_multirec_header {
} __attribute__ ((packed));
struct fru_multirec_powersupply {
unsigned short capacity : 12, __reserved1 : 4;
#if WORDS_BIGENDIAN
unsigned short capacity;
#else
unsigned short capacity : 12;
unsigned short __reserved1 : 4;
#endif
unsigned short peak_va;
unsigned char inrush_current;
unsigned char inrush_interval;
@ -136,9 +145,29 @@ struct fru_multirec_powersupply {
unsigned char lowend_freq;
unsigned char highend_freq;
unsigned char dropout_tolerance;
unsigned char predictive_fail : 1, pfc : 1, autoswitch : 1, hotswap : 1, tach : 1, __reserved2 : 3;
unsigned short peak_capacity : 12, peak_hold_up_time : 4;
unsigned char combined_voltage2 : 4, combined_voltage1 : 4;
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 3;
unsigned char tach : 1;
unsigned char hotswap : 1;
unsigned char autoswitch : 1;
unsigned char pfc : 1;
unsigned char predictive_fail : 1;
#else
unsigned char predictive_fail : 1;
unsigned char pfc : 1;
unsigned char autoswitch : 1;
unsigned char hotswap : 1;
unsigned char tach : 1;
unsigned char __reserved2 : 3;
#endif
unsigned short peak_cap_ht;
#if WORDS_BIGENDIAN
unsigned char combined_voltage1 : 4;
unsigned char combined_voltage2 : 4;
#else
unsigned char combined_voltage2 : 4;
unsigned char combined_voltage1 : 4;
#endif
unsigned short combined_capacity;
unsigned char rps_threshold;
} __attribute__ ((packed));
@ -148,7 +177,15 @@ static const char * combined_voltage_desc[] __attribute__((unused)) = {
};
struct fru_multirec_dcoutput {
unsigned char output_number : 4, __reserved : 3, standby : 1;
#if WORDS_BIGENDIAN
unsigned char standby : 1;
unsigned char __reserved : 3;
unsigned char output_number : 4;
#else
unsigned char output_number : 4;
unsigned char __reserved : 3;
unsigned char standby : 1;
#endif
short nominal_voltage;
short max_neg_dev;
short max_pos_dev;
@ -158,7 +195,13 @@ struct fru_multirec_dcoutput {
} __attribute__ ((packed));
struct fru_multirec_dcload {
unsigned char output_number : 4, __reserved : 4;
#if WORDS_BIGENDIAN
unsigned char __reserved : 4;
unsigned char output_number : 4;
#else
unsigned char output_number : 4;
unsigned char __reserved : 4;
#endif
short nominal_voltage;
short min_voltage;
short max_voltage;

View File

@ -689,7 +689,8 @@ void ipmi_spd_print(struct ipmi_intf * intf, unsigned char id)
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
memcpy(&fru, rsp->data, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
if (verbose > 1)
printf("fru.size = %d bytes (accessed by %s)\n",

View File

@ -41,6 +41,10 @@
#include <stdlib.h>
#include <string.h>
#if HAVE_CONFIG_H
# include <config.h>
#endif
extern int verbose;
extern void ipmi_spd_print(struct ipmi_intf * intf, unsigned char id);
@ -91,7 +95,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
memcpy(&fru, rsp->data, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
if (verbose > 1)
printf("fru.size = %d bytes (accessed by %s)\n",
@ -281,6 +286,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
struct fru_multirec_powersupply * ps;
struct fru_multirec_dcoutput * dc;
struct fru_multirec_dcload * dl;
unsigned short peak_capacity;
unsigned char peak_hold_up_time;
i = header.offset.multi;
@ -293,6 +300,19 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
case FRU_RECORD_TYPE_POWER_SUPPLY_INFORMATION:
ps = (struct fru_multirec_powersupply *) (fru_data + i + sizeof (struct fru_multirec_header));
#if WORDS_BIGENDIAN
ps->capacity = BSWAP_16(ps->capacity);
ps->peak_va = BSWAP_16(ps->peak_va);
ps->lowend_input1 = BSWAP_16(ps->lowend_input1);
ps->highend_input1 = BSWAP_16(ps->highend_input1);
ps->lowend_input2 = BSWAP_16(ps->lowend_input2);
ps->highend_input2 = BSWAP_16(ps->highend_input2);
ps->combined_capacity = BSWAP_16(ps->combined_capacity);
ps->peak_cap_ht = BSWAP_16(ps->peak_cap_ht);
#endif
peak_hold_up_time = (ps->peak_cap_ht & 0xf000) >> 12;
peak_capacity = ps->peak_cap_ht & 0x0fff;
printf (" Power Supply Record\n");
printf (" Capacity : %d W\n", ps->capacity);
printf (" Peak VA : %d VA\n", ps->peak_va);
@ -310,8 +330,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
ps->predictive_fail ? ps->rps_threshold ?
ps->tach ? "'Two pulses per rotation'" : "'One pulse per rotation'" :
ps->tach ? "'Failure on pin de-assertion'" : "'Failure on pin assertion'" : "");
printf (" Peak capacity : %d W\n", ps->peak_capacity);
printf (" Peak capacity holdup : %d s\n", ps->peak_hold_up_time);
printf (" Peak capacity : %d W\n", peak_capacity);
printf (" Peak capacity holdup : %d s\n", peak_hold_up_time);
if (ps->combined_capacity == 0)
printf (" Combined capacity : not specified\n");
else
@ -326,6 +346,15 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
case FRU_RECORD_TYPE_DC_OUTPUT:
dc = (struct fru_multirec_dcoutput *) (fru_data + i + sizeof (struct fru_multirec_header));
#if WORDS_BIGENDIAN
dc->nominal_voltage = BSWAP_16(dc->nominal_voltage);
dc->max_neg_dev = BSWAP_16(dc->max_neg_dev);
dc->max_pos_dev = BSWAP_16(dc->max_pos_dev);
dc->ripple_and_noise = BSWAP_16(dc->ripple_and_noise);
dc->min_current = BSWAP_16(dc->min_current);
dc->max_current = BSWAP_16(dc->max_current);
#endif
printf (" DC Output Record\n");
printf (" Output Number : %d\n", dc->output_number);
printf (" Standby power : %s\n", dc->standby ? "Yes" : "No");
@ -340,6 +369,15 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
case FRU_RECORD_TYPE_DC_LOAD:
dl = (struct fru_multirec_dcload *) (fru_data + i + sizeof (struct fru_multirec_header));
#if WORDS_BIGENDIAN
dl->nominal_voltage = BSWAP_16(dl->nominal_voltage);
dl->min_voltage = BSWAP_16(dl->min_voltage);
dl->max_voltage = BSWAP_16(dl->max_voltage);
dl->ripple_and_noise = BSWAP_16(dl->ripple_and_noise);
dl->min_current = BSWAP_16(dl->min_current);
dl->max_current = BSWAP_16(dl->max_current);
#endif
printf (" DC Load Record\n");
printf (" Output Number : %d\n", dl->output_number);
printf (" Nominal voltage : %.2f V\n", (double) dl->nominal_voltage / 100);