ID: 3608757 - ipmi_fru.h/ipmi_fru.c - various fixes

Fixed several bugs with printing out the Carrier and AMC connectivity
information with 'ipmitool -v fru'

There were several bugs that were caused due to using bitfields with
char types in ipmi_fru.h. GCC versions before v4.4 had a bug where
they did not pack the bitfields correctly if the bitfields were not
cleanly aligned with the underlying char type.

Fixed and cleaned up all other PICMG FRU records.

Commit for Dan Gora
This commit is contained in:
Zdenek Styblik 2013-04-22 08:37:13 +00:00
parent 0411186443
commit 2abad0e504
2 changed files with 434 additions and 330 deletions

View File

@ -397,20 +397,21 @@ struct fru_picmgext_amc_link_desc {
#define OEM_SWFW_NBLOCK_OFFSET 0x05 #define OEM_SWFW_NBLOCK_OFFSET 0x05
#define OEM_SWFW_FIELD_START_OFFSET 0x06 #define OEM_SWFW_FIELD_START_OFFSET 0x06
#define FRU_PICMGEXT_CHN_DESC_RECORD_SIZE 3
#ifdef HAVE_PRAGMA_PACK #ifdef HAVE_PRAGMA_PACK
#pragma pack(1) #pragma pack(1)
#endif #endif
struct fru_picmgext_chn_desc { struct fru_picmgext_chn_desc {
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
unsigned char remote_slot:8; unsigned int remote_slot:8;
unsigned char remote_chn:5; unsigned int remote_chn:5;
unsigned char local_chn:5; unsigned int local_chn:5;
unsigned char:6; unsigned int res:14;
#else #else
unsigned char:6; unsigned int res:14;
unsigned char local_chn:5; unsigned int local_chn:5;
unsigned char remote_chn:5; unsigned int remote_chn:5;
unsigned char remote_slot:8; unsigned int remote_slot:8;
#endif #endif
}ATTRIBUTE_PACKING; }ATTRIBUTE_PACKING;
#ifdef HAVE_PRAGMA_PACK #ifdef HAVE_PRAGMA_PACK
@ -507,28 +508,30 @@ struct fru_picmgext_amc_p2p_record {
#pragma pack(0) #pragma pack(0)
#endif #endif
#define FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE 3
#ifdef HAVE_PRAGMA_PACK #ifdef HAVE_PRAGMA_PACK
#pragma pack(1) #pragma pack(1)
#endif #endif
struct fru_picmgext_amc_channel_desc_record { struct fru_picmgext_amc_channel_desc_record {
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
unsigned char lane0port :5; unsigned int lane0port :5;
unsigned char lane1port :5; unsigned int lane1port :5;
unsigned char lane2port :5; unsigned int lane2port :5;
unsigned char lane3port :5; unsigned int lane3port :5;
unsigned char /*reserved */ :4; unsigned int /* reserved */ :12;
#else #else
unsigned char /*reserved */ :4; unsigned int /* reserved */ :12;
unsigned char lane3port :5; unsigned int lane3port :5;
unsigned char lane2port :5; unsigned int lane2port :5;
unsigned char lane1port :5; unsigned int lane1port :5;
unsigned char lane0port :5; unsigned int lane0port :5;
#endif #endif
}ATTRIBUTE_PACKING; }ATTRIBUTE_PACKING;
#ifdef HAVE_PRAGMA_PACK #ifdef HAVE_PRAGMA_PACK
#pragma pack(0) #pragma pack(0)
#endif #endif
#define FRU_PICMGEXT_AMC_LINK_DESC_RECORD_SIZE 5
#ifdef HAVE_PRAGMA_PACK #ifdef HAVE_PRAGMA_PACK
#pragma pack(1) #pragma pack(1)
#endif #endif
@ -552,27 +555,28 @@ struct fru_picmgext_amc_link_desc_record {
#define AMC_LINK_TYPE_EXT_STORAGE_SATA 0x01 #define AMC_LINK_TYPE_EXT_STORAGE_SATA 0x01
#define AMC_LINK_TYPE_EXT_STORAGE_SAS 0x02 #define AMC_LINK_TYPE_EXT_STORAGE_SAS 0x02
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
unsigned short channel_id :8; unsigned int channel_id :8;
unsigned short port_flag_0 :1; unsigned int port_flag_0 :1;
unsigned short port_flag_1 :1; unsigned int port_flag_1 :1;
unsigned short port_flag_2 :1; unsigned int port_flag_2 :1;
unsigned short port_flag_3 :1; unsigned int port_flag_3 :1;
unsigned short type :8; unsigned int type :8;
unsigned short type_ext :4; unsigned int type_ext :4;
unsigned short group_id :8; unsigned int group_id :8;
unsigned char asym_match :2; unsigned int asym_match :2;
unsigned char /* reserved */ :6; unsigned int /* reserved */ :30;
#else #else
unsigned char /* reserved */ :6; unsigned int group_id :8;
unsigned char asym_match :2; unsigned int type_ext :4;
unsigned short group_id :8; unsigned int type :8;
unsigned short type_ext :4; unsigned int port_flag_3 :1;
unsigned short type :8; unsigned int port_flag_2 :1;
unsigned short port_flag_3 :1; unsigned int port_flag_1 :1;
unsigned short port_flag_2 :1; unsigned int port_flag_0 :1;
unsigned short port_flag_1 :1; unsigned int channel_id :8;
unsigned short port_flag_0 :1;
unsigned short channel_id :8; unsigned int /* reserved */ :30;
unsigned int asym_match :2;
#endif #endif
}ATTRIBUTE_PACKING; }ATTRIBUTE_PACKING;
#ifdef HAVE_PRAGMA_PACK #ifdef HAVE_PRAGMA_PACK

View File

@ -2146,7 +2146,7 @@ static int ipmi_fru_picmg_ext_edit(uint8_t * fru_data,
static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length) static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
{ {
struct fru_multirec_oem_header *h; struct fru_multirec_oem_header *h;
int guid_count; int guid_count;
int offset = off; int offset = off;
int start_offset = off; int start_offset = off;
int i; int i;
@ -2156,20 +2156,21 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
switch (h->record_id) switch (h->record_id)
{ {
case FRU_PICMG_BACKPLANE_P2P: case FRU_PICMG_BACKPLANE_P2P:
{ {
uint8_t index; uint8_t index;
struct fru_picmgext_slot_desc * slot_d unsigned int data;
= (struct fru_picmgext_slot_desc*) &fru_data[offset]; struct fru_picmgext_slot_desc *slot_d;
slot_d =
(struct fru_picmgext_slot_desc*)&fru_data[offset];
offset += sizeof(struct fru_picmgext_slot_desc); offset += sizeof(struct fru_picmgext_slot_desc);
printf(" FRU_PICMG_BACKPLANE_P2P\n"); printf(" FRU_PICMG_BACKPLANE_P2P\n");
while (offset <= (start_offset+length)) { while (offset <= (start_offset+length)) {
printf("\n"); printf("\n");
printf(" Channel Type: "); printf(" Channel Type: ");
switch ( slot_d -> chan_type ) switch (slot_d->chan_type)
{ {
case 0x00: case 0x00:
case 0x07: case 0x07:
@ -2190,28 +2191,39 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
case 0x0c: case 0x0c:
printf("Update Channel IF\n"); printf("Update Channel IF\n");
break; break;
case 0x0d:
printf("ShMC Cross Connect\n");
break;
default: default:
printf("Unknown IF\n"); printf("Unknown IF (0x%x)\n",
slot_d->chan_type);
break; break;
} }
printf(" Slot Addr. : %02x\n", slot_d -> slot_addr ); printf(" Slot Addr. : %02x\n",
printf(" Channel Count: %i\n", slot_d -> chn_count); slot_d->slot_addr );
printf(" Channel Count: %i\n",
slot_d->chn_count);
for (index = 0; index < (slot_d -> chn_count); index++) { for (index = 0;
struct fru_picmgext_chn_desc * d index < (slot_d->chn_count);
= (struct fru_picmgext_chn_desc *) &fru_data[offset]; index++) {
struct fru_picmgext_chn_desc *d;
if (verbose) data = (fru_data[offset+0]) |
printf( " " (fru_data[offset+1] << 8) |
(fru_data[offset+2] << 16);
d = (struct fru_picmgext_chn_desc *)&data;
if (verbose) {
printf( " "
"Chn: %02x -> " "Chn: %02x -> "
"Chn: %02x in " "Chn: %02x in "
"Slot: %02x\n", "Slot: %02x\n",
d->local_chn, d->remote_chn, d->remote_slot); d->local_chn,
d->remote_chn,
offset += sizeof(struct fru_picmgext_chn_desc); d->remote_slot);
}
offset += FRU_PICMGEXT_CHN_DESC_RECORD_SIZE;
} }
slot_d = (struct fru_picmgext_slot_desc*)&fru_data[offset];
slot_d = (struct fru_picmgext_slot_desc*) &fru_data[offset];
offset += sizeof(struct fru_picmgext_slot_desc); offset += sizeof(struct fru_picmgext_slot_desc);
} }
} }
@ -2219,11 +2231,25 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
case FRU_PICMG_ADDRESS_TABLE: case FRU_PICMG_ADDRESS_TABLE:
{ {
unsigned char entries = 0; unsigned int hwaddr;
unsigned char i; unsigned int sitetype;
unsigned int sitenum;
unsigned int entries;
unsigned int i;
char *picmg_site_type_strings[] = {
"AdvancedTCA Board",
"Power Entry",
"Shelf FRU Information",
"Dedicated ShMC",
"Fan Tray",
"Fan Filter Tray",
"Alarm",
"AdvancedMC Module",
"PMC",
"Rear Transition Module"};
printf(" FRU_PICMG_ADDRESS_TABLE\n"); printf(" FRU_PICMG_ADDRESS_TABLE\n");
printf(" Type/Len: 0x%02x\n", fru_data[offset++]); printf(" Type/Len: 0x%02x\n", fru_data[offset++]);
printf(" Shelf Addr: "); printf(" Shelf Addr: ");
for (i=0;i<20;i++) { for (i=0;i<20;i++) {
@ -2235,62 +2261,115 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
printf(" Addr Table Entries: 0x%02x\n", entries); printf(" Addr Table Entries: 0x%02x\n", entries);
for (i=0; i<entries; i++) { for (i=0; i<entries; i++) {
printf(" HWAddr: 0x%02x - SiteNum: 0x%02x - SiteType: 0x%02x \n", hwaddr = fru_data[offset];
fru_data[offset], fru_data[offset+1], fru_data[offset+2]); sitenum = fru_data[offset + 1];
offset+= 3; sitetype = fru_data[offset + 2];
printf(
" HWAddr: 0x%02x (0x%02x) SiteNum: %d SiteType: 0x%02x %s\n",
hwaddr, hwaddr * 2,
sitenum, sitetype,
(sitetype < 0xa) ?
picmg_site_type_strings[sitetype] :
"Reserved");
offset += 3;
} }
} }
break; break;
case FRU_PICMG_SHELF_POWER_DIST: case FRU_PICMG_SHELF_POWER_DIST:
{ {
unsigned char i,j; unsigned int entries;
unsigned char feeds = 0; unsigned int feeds;
unsigned int feedcnt;
unsigned int hwaddr;
unsigned int i;
unsigned int id;
unsigned int j;
unsigned int maxext;
unsigned int maxint;
unsigned int minexp;
printf(" FRU_PICMG_SHELF_POWER_DIST\n"); printf(" FRU_PICMG_SHELF_POWER_DIST\n");
feeds = fru_data[offset++]; feeds = fru_data[offset++];
printf(" Number of Power Feeds: 0x%02x\n", feeds); printf(" Number of Power Feeds: 0x%02x\n",
feeds);
for (i=0; i<feeds; i++) { for (i=0; i<feeds; i++) {
unsigned char entries; printf(" Feed %d:\n", i);
maxext = fru_data[offset] |
printf(" Max Ext Current: 0x%04x\n", fru_data[offset+0] | (fru_data[offset+1]<<8)); (fru_data[offset+1] << 8);
offset += 2; offset += 2;
printf(" Max Int Current: 0x%04x\n", fru_data[offset+0] | (fru_data[offset+1]<<8)); maxint = fru_data[offset] |
(fru_data[offset+1] << 8);
offset += 2; offset += 2;
printf(" Min Exp Voltage: 0x%02x\n", fru_data[offset++]); minexp = fru_data[offset];
offset += 1;
entries = fru_data[offset];
offset += 1;
entries = fru_data[offset++]; printf(
printf(" Feed to FRU count: 0x%02x\n", entries); " Max External Current: %d.%d Amps (0x%04x)\n",
maxext / 10, maxext % 10, maxext);
if (maxint < 0xffff) {
printf(
" Max Internal Current: %d.%d Amps (0x%04x)\n",
maxint / 10, maxint % 10,
maxint);
} else {
printf(
" Max Internal Current: Not Specified\n");
}
for (j=0; j<entries; j++) { if (minexp >= 0x48 && minexp <= 0x90) {
printf(" HW: 0x%02x", fru_data[offset++]); printf(
printf(" FRU ID: 0x%02x\n", fru_data[offset++]); " Min Expected Voltage: -%02d.%dV\n",
minexp / 2, (minexp % 2) * 5);
} else {
printf(
" Min Expected Voltage: -36V (actual invalid value 0x%x)\n",
36, minexp);
}
for (j=0; j < entries; j++) {
hwaddr = fru_data[offset++];
id = fru_data[offset++];
printf(
" FRU HW Addr: 0x%02x (0x%02x)",
hwaddr, hwaddr * 2);
printf(
" FRU ID: 0x%02x\n",
id);
} }
} }
} }
break; break;
case FRU_PICMG_SHELF_ACTIVATION: case FRU_PICMG_SHELF_ACTIVATION:
{ {
unsigned char i; unsigned int i;
unsigned char count = 0; unsigned int count = 0;
printf(" FRU_PICMG_SHELF_ACTIVATION\n"); printf(" FRU_PICMG_SHELF_ACTIVATION\n");
printf(
printf(" Allowance for FRU Act Readiness: 0x%02x\n", fru_data[offset++]); " Allowance for FRU Act Readiness: 0x%02x\n",
fru_data[offset++]);
count = fru_data[offset++]; count = fru_data[offset++];
printf(" FRU activation and Power Desc Cnt: 0x%02x\n", count); printf(
" FRU activation and Power Desc Cnt: 0x%02x\n",
count);
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
printf(" HW Addr: 0x%02x ", fru_data[offset++]); printf(" HW Addr: 0x%02x ",
printf(" FRU ID: 0x%02x ", fru_data[offset++]); fru_data[offset++]);
printf(" Max FRU Power: 0x%04x ", fru_data[offset+0] | (fru_data[offset+1]<<8)); printf(" FRU ID: 0x%02x ",
fru_data[offset++]);
printf(" Max FRU Power: 0x%04x ",
fru_data[offset+0] |
(fru_data[offset+1]<<8));
offset += 2; offset += 2;
printf(" Config: 0x%02x \n", fru_data[offset++]); printf(" Config: 0x%02x \n",
fru_data[offset++]);
} }
} }
break; break;
@ -2308,28 +2387,32 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
int j; int j;
printf(" GUID [%2d]: 0x", i); printf(" GUID [%2d]: 0x", i);
for (j=0; j < sizeof(struct fru_picmgext_guid); j++) { for (j=0; j < sizeof(struct fru_picmgext_guid);
j++) {
printf("%02x", fru_data[offset+j]); printf("%02x", fru_data[offset+j]);
} }
printf("\n"); printf("\n");
offset += sizeof(struct fru_picmgext_guid); offset += sizeof(struct fru_picmgext_guid);
} }
printf("\n"); printf("\n");
for (; offset < off + length; offset += sizeof(struct fru_picmgext_link_desc)) { for (; offset < off + length;
offset += sizeof(struct fru_picmgext_link_desc)) {
/* to solve little endian /big endian problem */ /* to solve little endian /big endian problem */
unsigned long data = (fru_data[offset+0]) struct fru_picmgext_link_desc *d;
| (fru_data[offset+1] << 8) unsigned int data = (fru_data[offset+0]) |
| (fru_data[offset+2] << 16) (fru_data[offset+1] << 8) |
| (fru_data[offset+3] << 24); (fru_data[offset+2] << 16) |
(fru_data[offset+3] << 24);
d = (struct fru_picmgext_link_desc *) &data;
struct fru_picmgext_link_desc * d = (struct fru_picmgext_link_desc *) &data; printf(" Link Grouping ID: 0x%02x\n",
d->grouping);
printf(" Link Grouping ID: 0x%02x\n", d->grouping); printf(" Link Type Extension: 0x%02x - ",
printf(" Link Type Extension: 0x%02x - ", d->ext); d->ext);
if (d->type == FRU_PICMGEXT_LINK_TYPE_BASE){ if (d->type == FRU_PICMGEXT_LINK_TYPE_BASE) {
switch (d->ext) switch (d->ext)
{ {
case 0: case 0:
@ -2342,7 +2425,7 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
printf("Unknwon\n"); printf("Unknwon\n");
break; break;
} }
}else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET){ } else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET) {
switch (d->ext) switch (d->ext)
{ {
case 0: case 0:
@ -2358,21 +2441,19 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
printf("Unknwon\n"); printf("Unknwon\n");
break; break;
} }
} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND) {
}else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND){
printf("Unknwon\n"); printf("Unknwon\n");
}else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR){ } else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR) {
printf("Unknwon\n"); printf("Unknwon\n");
}else if (d->type == FRU_PICMGEXT_LINK_TYPE_PCIE){ } else if (d->type == FRU_PICMGEXT_LINK_TYPE_PCIE) {
printf("Unknwon\n"); printf("Unknwon\n");
}else } else {
{
printf("Unknwon\n"); printf("Unknwon\n");
} }
printf(" Link Type: 0x%02x - ",d->type); printf(" Link Type: 0x%02x - ",
if (d->type == 0 || d->type == 0xff) d->type);
{ if (d->type == 0 || d->type == 0xff) {
printf("Reserved\n"); printf("Reserved\n");
} }
else if (d->type >= 0x06 && d->type <= 0xef) { else if (d->type >= 0x06 && d->type <= 0xef) {
@ -2405,27 +2486,30 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
} }
} }
printf(" Link Designator: \n"); printf(" Link Designator: \n");
printf(" Port Flag: 0x%02x\n", d->desig_port); printf(" Port Flag: 0x%02x\n",
printf(" Interface: 0x%02x - ", d->desig_if); d->desig_port);
switch (d->desig_if) printf(" Interface: 0x%02x - ",
{ d->desig_if);
case FRU_PICMGEXT_DESIGN_IF_BASE: switch (d->desig_if)
printf("Base Interface\n"); {
break; case FRU_PICMGEXT_DESIGN_IF_BASE:
case FRU_PICMGEXT_DESIGN_IF_FABRIC: printf("Base Interface\n");
printf("Fabric Interface\n"); break;
break; case FRU_PICMGEXT_DESIGN_IF_FABRIC:
case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL: printf("Fabric Interface\n");
printf("Update Channel\n"); break;
break; case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL:
case FRU_PICMGEXT_DESIGN_IF_RESERVED: printf("Update Channel\n");
printf("Reserved\n"); break;
break; case FRU_PICMGEXT_DESIGN_IF_RESERVED:
default: printf("Reserved\n");
printf("Invalid"); break;
break; default:
} printf("Invalid");
printf(" Channel Number: 0x%02x\n", d->desig_channel); break;
}
printf(" Channel Number: 0x%02x\n",
d->desig_channel);
printf("\n"); printf("\n");
} }
@ -2438,8 +2522,8 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
current = fru_data[offset]; current = fru_data[offset];
printf(" Current draw(@12V): %.2f A [ %.2f Watt ]\n", printf(" Current draw(@12V): %.2f A [ %.2f Watt ]\n",
(float)current / 10.0f, (float)current / 10.0f,
(float)current / 10.0f * 12.0f); (float)current / 10.0f * 12.0f);
printf("\n"); printf("\n");
} }
break; break;
@ -2452,72 +2536,69 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
max_current = fru_data[offset]; max_current = fru_data[offset];
max_current |= fru_data[++offset]<<8; max_current |= fru_data[++offset]<<8;
printf(" Maximum Internal Current(@12V): %.2f A [ %.2f Watt ]\n", printf(" Maximum Internal Current(@12V): %.2f A [ %.2f Watt ]\n",
(float)max_current / 10.0f, (float)max_current / 10.0f,
(float)max_current / 10.0f * 12.0f); (float)max_current / 10.0f * 12.0f);
printf(" Module Activation Readiness: %i sec.\n", fru_data[++offset]); printf(" Module Activation Readiness: %i sec.\n", fru_data[++offset]);
printf(" Descriptor Count: %i\n", fru_data[++offset]); printf(" Descriptor Count: %i\n", fru_data[++offset]);
printf("\n"); printf("\n");
for(++offset; offset < off + length; offset += sizeof(struct fru_picmgext_activation_record)) for(++offset; offset < off + length;
offset += sizeof(struct fru_picmgext_activation_record))
{ {
struct fru_picmgext_activation_record * a = struct fru_picmgext_activation_record *a;
(struct fru_picmgext_activation_record *) &fru_data[offset]; a = (struct fru_picmgext_activation_record *)&fru_data[offset];
printf(" IPMB-Address: 0x%x\n",
printf(" IPMB-Address: 0x%x\n", a->ibmb_addr); a->ibmb_addr);
printf(" Max. Module Current: %.2f A\n", (float)a->max_module_curr / 10.0f); printf(" Max. Module Current: %.2f A\n",
(float)a->max_module_curr / 10.0f);
printf("\n"); printf("\n");
} }
} }
break; break;
case FRU_AMC_CARRIER_P2P: case FRU_AMC_CARRIER_P2P:
printf(" FRU_CARRIER_P2P\n");
{ {
uint16_t index; uint16_t index;
printf(" FRU_CARRIER_P2P\n");
for(; offset < off + length; ) for(; offset < off + length; ) {
{
struct fru_picmgext_carrier_p2p_record * h = struct fru_picmgext_carrier_p2p_record * h =
(struct fru_picmgext_carrier_p2p_record *) &fru_data[offset]; (struct fru_picmgext_carrier_p2p_record *)&fru_data[offset];
printf("\n"); printf("\n");
printf(" Resource ID: %i", h->resource_id & 0x07); printf(" Resource ID: %i",
printf(" Type: "); (h->resource_id & 0x07));
printf(" Type: ");
if ((h->resource_id>>7) == 1) { if ((h->resource_id>>7) == 1) {
printf("AMC\n"); printf("AMC\n");
} else { } else {
printf("Local\n"); printf("Local\n");
} }
printf(" Descriptor Count: %i\n", h->p2p_count); printf(" Descriptor Count: %i\n",
h->p2p_count);
offset += sizeof(struct fru_picmgext_carrier_p2p_record); offset += sizeof(struct fru_picmgext_carrier_p2p_record);
for (index = 0; index < h->p2p_count; index++) {
for (index = 0; index < h->p2p_count; index++)
{
/* to solve little endian /big endian problem */ /* to solve little endian /big endian problem */
unsigned char data[3]; unsigned char data[3];
struct fru_picmgext_carrier_p2p_descriptor * desc; struct fru_picmgext_carrier_p2p_descriptor * desc;
# ifndef WORDS_BIGENDIAN
#ifndef WORDS_BIGENDIAN
data[0] = fru_data[offset+0]; data[0] = fru_data[offset+0];
data[1] = fru_data[offset+1]; data[1] = fru_data[offset+1];
data[2] = fru_data[offset+2]; data[2] = fru_data[offset+2];
#else # else
data[0] = fru_data[offset+2]; data[0] = fru_data[offset+2];
data[1] = fru_data[offset+1]; data[1] = fru_data[offset+1];
data[2] = fru_data[offset+0]; data[2] = fru_data[offset+0];
#endif # endif
desc = (struct fru_picmgext_carrier_p2p_descriptor*)&data; desc = (struct fru_picmgext_carrier_p2p_descriptor*)&data;
printf(" Port: %02d\t-> Remote Port: %02d\t", printf(" Port: %02d\t-> Remote Port: %02d\t",
desc->local_port, desc->remote_port); desc->local_port, desc->remote_port);
if((desc->remote_resource_id >> 7) == 1) if ((desc->remote_resource_id >> 7) == 1) {
printf("[ AMC ID: %02d ]\n", desc->remote_resource_id & 0x0F); printf("[ AMC ID: %02d ]\n",
else desc->remote_resource_id & 0x0F);
printf("[ local ID: %02d ]\n", desc->remote_resource_id & 0x0F); } else {
printf("[ local ID: %02d ]\n",
desc->remote_resource_id & 0x0F);
}
offset += sizeof(struct fru_picmgext_carrier_p2p_descriptor); offset += sizeof(struct fru_picmgext_carrier_p2p_descriptor);
} }
} }
@ -2525,174 +2606,193 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
break; break;
case FRU_AMC_P2P: case FRU_AMC_P2P:
printf(" FRU_AMC_P2P\n");
{ {
unsigned int index; unsigned int index;
unsigned char channel_count; unsigned char channel_count;
struct fru_picmgext_amc_p2p_record * h; struct fru_picmgext_amc_p2p_record * h;
printf(" FRU_AMC_P2P\n");
guid_count = fru_data[offset++]; guid_count = fru_data[offset];
printf(" GUID count: %2d\n", guid_count); printf(" GUID count: %2d\n", guid_count);
for (i = 0 ; i < guid_count; i++) {
for (i = 0 ; i < guid_count; i++ )
{
int j; int j;
printf(" GUID %2d: ", i); printf(" GUID %2d: ", i);
for (j=0; j < sizeof(struct fru_picmgext_guid);
for (j=0; j < sizeof(struct fru_picmgext_guid); j++) { j++) {
printf("%02x", fru_data[offset+j]); printf("%02x", fru_data[offset+j]);
offset += sizeof(struct fru_picmgext_guid);
printf("\n");
} }
h = (struct fru_picmgext_amc_p2p_record *)&fru_data[++offset];
offset += sizeof(struct fru_picmgext_guid); printf(" %s",
printf("\n"); (h->record_type ?
} "AMC Module:" : "On-Carrier Device"));
printf(" Resource ID: %i\n", h->resource_id);
h = (struct fru_picmgext_amc_p2p_record *) &fru_data[offset]; offset += sizeof(struct fru_picmgext_amc_p2p_record);
printf(" %s", (h->record_type?"AMC Module:":"On-Carrier Device")); channel_count = fru_data[offset++];
printf(" Recource ID: %i\n", h->resource_id); printf(" Descriptor Count: %i\n",
channel_count);
offset += sizeof(struct fru_picmgext_amc_p2p_record); for (index = 0; index < channel_count; index++) {
unsigned int data;
channel_count = fru_data[offset++]; struct fru_picmgext_amc_channel_desc_record *d;
printf(" Descriptor Count: %i\n", channel_count); /* pack the data in little endian format.
* Stupid intel...
for (index=0 ;index < channel_count; index++) */
{ data = fru_data[offset] |
struct fru_picmgext_amc_channel_desc_record * d = (fru_data[offset + 1] << 8) |
(struct fru_picmgext_amc_channel_desc_record *) &fru_data[offset]; (fru_data[offset + 2] << 16);
d = (struct fru_picmgext_amc_channel_desc_record *)&data;
printf(" Lane 0 Port: %i\n", d->lane0port); printf(" Lane 0 Port: %i\n",
printf(" Lane 1 Port: %i\n", d->lane1port); d->lane0port);
printf(" Lane 2 Port: %i\n", d->lane2port); printf(" Lane 1 Port: %i\n",
printf(" Lane 3 Port: %i\n\n", d->lane3port); d->lane1port);
printf(" Lane 2 Port: %i\n",
d->lane2port);
offset += sizeof(struct fru_picmgext_amc_channel_desc_record); printf(" Lane 3 Port: %i\n\n",
} d->lane3port);
offset += FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE;
for ( ; offset < off + length;)
{
struct fru_picmgext_amc_link_desc_record * l =
(struct fru_picmgext_amc_link_desc_record *) &fru_data[offset];
printf(" Link Designator: Channel ID: %i\n"
" Port Flag 0: %s%s%s%s\n",
l->channel_id,
(l->port_flag_0)?"o":"-",
(l->port_flag_1)?"o":"-",
(l->port_flag_2)?"o":"-",
(l->port_flag_3)?"o":"-" );
switch (l->type)
{
/* AMC.1 */
case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE:
printf(" Link Type: %02x - "
"AMC.1 PCI Express\n", l->type);
switch (l->type_ext)
{
case AMC_LINK_TYPE_EXT_PCIE_G1_NSSC:
printf(" Link Type Ext: %i - "
" Gen 1 capable - non SSC\n", l->type_ext);
break;
case AMC_LINK_TYPE_EXT_PCIE_G1_SSC:
printf(" Link Type Ext: %i - "
" Gen 1 capable - SSC\n", l->type_ext);
break;
case AMC_LINK_TYPE_EXT_PCIE_G2_NSSC:
printf(" Link Type Ext: %i - "
" Gen 2 capable - non SSC\n", l->type_ext);
break;
case AMC_LINK_TYPE_EXT_PCIE_G2_SSC:
printf(" Link Type Ext: %i - "
" Gen 2 capable - SSC\n", l->type_ext);
break;
default:
printf(" Link Type Ext: %i - "
" Invalid\n", l->type_ext);
break;
}
break;
/* AMC.1 */
case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS1:
case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS2:
printf(" Link Type: %02x - "
"AMC.1 PCI Express Advanced Switching\n", l->type);
printf(" Link Type Ext: %i\n", l->type_ext);
break;
/* AMC.2 */
case FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET:
printf(" Link Type: %02x - "
"AMC.2 Ethernet\n", l->type);
switch (l->type_ext)
{
case AMC_LINK_TYPE_EXT_ETH_1000_BX:
printf(" Link Type Ext: %i - "
" 1000Base-Bx (SerDES Gigabit) Ethernet Link\n", l->type_ext);
break;
case AMC_LINK_TYPE_EXT_ETH_10G_XAUI:
printf(" Link Type Ext: %i - "
" 10Gbit XAUI Ethernet Link\n", l->type_ext);
break;
default:
printf(" Link Type Ext: %i - "
" Invalid\n", l->type_ext);
break;
}
break;
/* AMC.3 */
case FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE:
printf(" Link Type: %02x - "
"AMC.3 Storage\n", l->type);
switch (l->type_ext)
{
case AMC_LINK_TYPE_EXT_STORAGE_FC:
printf(" Link Type Ext: %i - "
" Fibre Channel\n", l->type_ext);
break;
case AMC_LINK_TYPE_EXT_STORAGE_SATA:
printf(" Link Type Ext: %i - "
" Serial ATA\n", l->type_ext);
break;
case AMC_LINK_TYPE_EXT_STORAGE_SAS:
printf(" Link Type Ext: %i - "
" Serial Attached SCSI\n", l->type_ext);
break;
default:
printf(" Link Type Ext: %i - "
" Invalid\n", l->type_ext);
break;
}
break;
/* AMC.4 */
case FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO:
printf(" Link Type: %02x - "
"AMC.4 Serial Rapid IO\n", l->type);
printf(" Link Type Ext: %i\n", l->type_ext);
break;
default:
printf(" Link Type: %02x - "
"reserved or OEM GUID", l->type);
printf(" Link Type Ext: %i\n", l->type_ext);
break;
} }
for (; offset < off + length;) {
unsigned int data[2];
struct fru_picmgext_amc_link_desc_record *l;
l = (struct fru_picmgext_amc_link_desc_record *)&data[0];
data[0] = fru_data[offset] |
(fru_data[offset + 1] << 8) |
(fru_data[offset + 2] << 16) |
(fru_data[offset + 3] << 24);
data[1] = fru_data[offset + 4];
printf( " Link Designator: Channel ID: %i\n"
" Port Flag 0: %s%s%s%s\n",
l->channel_id,
(l->port_flag_0)?"o":"-",
(l->port_flag_1)?"o":"-",
(l->port_flag_2)?"o":"-",
(l->port_flag_3)?"o":"-" );
switch (l->type) {
case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE:
/* AMC.1 */
printf( " Link Type: %02x - "
"AMC.1 PCI Express\n", l->type);
switch (l->type_ext) {
case AMC_LINK_TYPE_EXT_PCIE_G1_NSSC:
printf( " Link Type Ext: %i - "
" Gen 1 capable - non SSC\n",
l->type_ext);
break;
case AMC_LINK_TYPE_EXT_PCIE_G1_SSC:
printf( " Link Type Ext: %i - "
" Gen 1 capable - SSC\n",
l->type_ext);
break;
case AMC_LINK_TYPE_EXT_PCIE_G2_NSSC:
printf( " Link Type Ext: %i - "
" Gen 2 capable - non SSC\n",
l->type_ext);
break;
case AMC_LINK_TYPE_EXT_PCIE_G2_SSC:
printf( " Link Type Ext: %i - "
" Gen 2 capable - SSC\n",
l->type_ext);
break;
default:
printf( " Link Type Ext: %i - "
" Invalid\n",
l->type_ext);
break;
}
break;
printf(" Link group Id: %i\n", l->group_id); case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS1:
printf(" Link Asym Match: %i\n\n",l->asym_match); case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS2:
/* AMC.1 */
printf( " Link Type: %02x - "
"AMC.1 PCI Express Advanced Switching\n",
l->type);
printf(" Link Type Ext: %i\n",
l->type_ext);
break;
offset += sizeof(struct fru_picmgext_amc_link_desc_record); case FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET:
/* AMC.2 */
printf( " Link Type: %02x - "
"AMC.2 Ethernet\n",
l->type);
switch (l->type_ext) {
case AMC_LINK_TYPE_EXT_ETH_1000_BX:
printf( " Link Type Ext: %i - "
" 1000Base-Bx (SerDES Gigabit) Ethernet Link\n",
l->type_ext);
break;
case AMC_LINK_TYPE_EXT_ETH_10G_XAUI:
printf( " Link Type Ext: %i - "
" 10Gbit XAUI Ethernet Link\n",
l->type_ext);
break;
default:
printf( " Link Type Ext: %i - "
" Invalid\n",
l->type_ext);
break;
}
break;
case FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE:
/* AMC.3 */
printf( " Link Type: %02x - "
"AMC.3 Storage\n",
l->type);
switch (l->type_ext) {
case AMC_LINK_TYPE_EXT_STORAGE_FC:
printf( " Link Type Ext: %i - "
" Fibre Channel\n",
l->type_ext);
break;
case AMC_LINK_TYPE_EXT_STORAGE_SATA:
printf( " Link Type Ext: %i - "
" Serial ATA\n",
l->type_ext);
break;
case AMC_LINK_TYPE_EXT_STORAGE_SAS:
printf( " Link Type Ext: %i - "
" Serial Attached SCSI\n",
l->type_ext);
break;
default:
printf( " Link Type Ext: %i - "
" Invalid\n",
l->type_ext);
break;
}
break;
case FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO:
/* AMC.4 */
printf( " Link Type: %02x - "
"AMC.4 Serial Rapid IO\n",
l->type);
printf(" Link Type Ext: %i\n",
l->type_ext);
break;
default:
printf( " Link Type: %02x - "
"reserved or OEM GUID",
l->type);
printf(" Link Type Ext: %i\n",
l->type_ext);
break;
}
printf(" Link group Id: %i\n",
l->group_id);
printf(" Link Asym Match: %i\n\n",
l->asym_match);
offset += FRU_PICMGEXT_AMC_LINK_DESC_RECORD_SIZE;
}
} }
} }
break; break;
@ -2708,8 +2808,8 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
siteCount = fru_data[offset++]; siteCount = fru_data[offset++];
printf(" AMC.0 extension version: R%d.%d\n", printf(" AMC.0 extension version: R%d.%d\n",
(extVersion >> 0)& 0x0F, (extVersion >> 0)& 0x0F,
(extVersion >> 4)& 0x0F ); (extVersion >> 4)& 0x0F );
printf(" Carrier Sie Number Cnt: %d\n", siteCount); printf(" Carrier Sie Number Cnt: %d\n", siteCount);
for (i = 0 ; i < siteCount; i++ ){ for (i = 0 ; i < siteCount; i++ ){
@ -2789,8 +2889,8 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
indirect_cnt = fru_data[offset++]; indirect_cnt = fru_data[offset++];
direct_cnt = fru_data[offset++]; direct_cnt = fru_data[offset++];
printf(" Cnt: Indirect 0x%02x / Direct 0x%02x\n", printf(" Cnt: Indirect 0x%02x / Direct 0x%02x\n",
indirect_cnt, indirect_cnt,
direct_cnt ); direct_cnt);
/* indirect desc */ /* indirect desc */
for(j=0; j<indirect_cnt; j++){ for(j=0; j<indirect_cnt; j++){
@ -2823,12 +2923,12 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
offset += 4; offset += 4;
printf(" - Feature: 0x%02x - PLL: %x / Asym: %s\n", printf(" - Feature: 0x%02x - PLL: %x / Asym: %s\n",
feature, feature,
(feature > 1) & 1, (feature > 1) & 1,
(feature&1)?"Source":"Receiver"); (feature&1)?"Source":"Receiver");
printf(" Family: 0x%02x - AccLVL: 0x%02x\n", family, accuracy); printf(" Family: 0x%02x - AccLVL: 0x%02x\n", family, accuracy);
printf(" FRQ: %-9d - min: %-9d - max: %-9d\n", printf(" FRQ: %-9ld - min: %-9ld - max: %-9ld\n",
(int)freq, (int)min_freq, (int)max_freq); freq, min_freq, max_freq);
} }
printf("\n"); printf("\n");
} }