Due to a bug in gcc where unaligned bit fields were not packed correctly before gcc 4.4, we changed the fru_picmgext_amc_channel_desc_record and fru_picmgext_amc_link_desc_record structures to use larger types to be packed correctly. This then requires us to use the FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE and FRU_PICMGEXT_AMC_LINK_DESC_RECORD_SIZE defines instead of sizeof for these structures.
Updated ipmi_ek_create_amc_p2p_record() and ipmi_ek_display_amc_p2p_record() to read data in the correct byte order on both big and little endian machines. Signed-off-by: Dan Gora <d...@adax.com> --- ipmitool/lib/ipmi_ekanalyzer.c | 90 ++++++++++++++++++++++++++++----------- 1 files changed, 64 insertions(+), 26 deletions(-) diff --git a/ipmitool/lib/ipmi_ekanalyzer.c b/ipmitool/lib/ipmi_ekanalyzer.c index fb4f66a..f61387f 100644 --- a/ipmitool/lib/ipmi_ekanalyzer.c +++ b/ipmitool/lib/ipmi_ekanalyzer.c @@ -2226,7 +2226,7 @@ ipmi_ek_create_amc_p2p_record( struct ipmi_ek_multi_header * record, /*Calculate link descriptor count*/ amc_record->link_desc_count = ( (record->header.len) - 8 - (SIZE_OF_GUID*amc_record->guid_count) - - ( sizeof(struct fru_picmgext_amc_channel_desc_record)* + (FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE * amc_record->ch_count ) )/5 ; } @@ -2235,7 +2235,7 @@ ipmi_ek_create_amc_p2p_record( struct ipmi_ek_multi_header * record, amc_record->ch_count = record->data[index_data++]; /*Calculate link descriptor count see spec AMC.0 for detail*/ amc_record->link_desc_count = ( (record->header.len) - 8 - - ( sizeof(struct fru_picmgext_amc_channel_desc_record)* + (FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE * amc_record->ch_count ) ) / 5; } @@ -2245,10 +2245,20 @@ ipmi_ek_create_amc_p2p_record( struct ipmi_ek_multi_header * record, amc_record->ch_desc = malloc ( (amc_record->ch_count) * \ sizeof(struct fru_picmgext_amc_channel_desc_record)); for (ch_index = 0; ch_index < amc_record->ch_count; ch_index++){ - memcpy(&amc_record->ch_desc[ch_index], &record->data[index_data], - sizeof(struct fru_picmgext_amc_channel_desc_record) ); - - index_data += sizeof(struct fru_picmgext_amc_channel_desc_record) ; + unsigned int data; + struct fru_picmgext_amc_channel_desc_record *src, *dst; + data = record->data[index_data] | + (record->data[index_data + 1] << 8) | + (record->data[index_data + 2] << 16); + + src = (struct fru_picmgext_amc_channel_desc_record *) &data; + dst = (struct fru_picmgext_amc_channel_desc_record *) + &amc_record->ch_desc[ch_index]; + dst->lane0port = src->lane0port; + dst->lane1port = src->lane1port; + dst->lane2port = src->lane2port; + dst->lane3port = src->lane3port; + index_data += FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE; } } if (amc_record->link_desc_count > 0){ @@ -2256,9 +2266,27 @@ ipmi_ek_create_amc_p2p_record( struct ipmi_ek_multi_header * record, amc_record->link_desc = malloc ( amc_record->link_desc_count * sizeof(struct fru_picmgext_amc_link_desc_record) ); for (i = 0; i< amc_record->link_desc_count; i++ ){ - memcpy (&amc_record->link_desc[i], &record->data[index_data], - sizeof(struct fru_picmgext_amc_link_desc_record) ); - index_data += sizeof (struct fru_picmgext_amc_link_desc_record); + unsigned int data[2]; + struct fru_picmgext_amc_link_desc_record *src, *dst; + data[0] = record->data[index_data] | + (record->data[index_data + 1] << 8) | + (record->data[index_data + 2] << 16) | + (record->data[index_data + 3] << 24); + data[1] = record->data[index_data + 4]; + src = (struct fru_picmgext_amc_link_desc_record*) &data; + dst = (struct fru_picmgext_amc_link_desc_record*) + &amc_record->link_desc[i]; + + dst->channel_id = src->channel_id; + dst->port_flag_0 = src->port_flag_0; + dst->port_flag_1 = src->port_flag_1; + dst->port_flag_2 = src->port_flag_2; + dst->port_flag_3 = src->port_flag_3; + dst->type = src->type; + dst->type_ext = src->type_ext; + dst->group_id = src->group_id; + dst->asym_match = src->asym_match; + index_data += FRU_PICMGEXT_AMC_LINK_DESC_RECORD_SIZE; } } else{ @@ -3592,31 +3620,41 @@ ipmi_ek_display_amc_p2p_record( struct ipmi_ek_multi_header * record ) if ( ch_count > 0 ){ for ( index = 0; index < ch_count; index++ ){ + unsigned int data; struct fru_picmgext_amc_channel_desc_record * ch_desc; printf(" AMC Channel Descriptor {%02x%02x%02x}\n", record->data[index_data+2], record->data[index_data+1], record->data[index_data] ); + data = record->data[index_data] | + (record->data[index_data + 1] << 8) | + (record->data[index_data + 2] << 16); /*Warning: For gcc version between 4.0 and 4.3 this code doesnt work*/ - ch_desc = ( struct fru_picmgext_amc_channel_desc_record * )\ - &record->data[index_data]; + ch_desc = ( struct fru_picmgext_amc_channel_desc_record * ) &data; printf(" Lane 0 Port: 0x%02x\n", ch_desc->lane0port); printf(" Lane 1 Port: 0x%02x\n", ch_desc->lane1port); printf(" Lane 2 Port: 0x%02x\n", ch_desc->lane2port); printf(" Lane 3 Port: 0x%02x\n\n", ch_desc->lane3port); - index_data += sizeof (struct fru_picmgext_amc_channel_desc_record) ; + index_data += FRU_PICMGEXT_AMC_CHANNEL_DESC_RECORD_SIZE; } } while ( index_data < record->header.len ){ /*Warning: For gcc version between 4.0 and 4.3 this code doesnt work*/ - struct fru_picmgext_amc_link_desc_record * link_desc = - (struct fru_picmgext_amc_link_desc_record *)&record->data[index_data]; + unsigned int data[2]; + struct fru_picmgext_amc_link_desc_record *link_desc; + data[0] = record->data[index_data] | + (record->data[index_data + 1] << 8) | + (record->data[index_data + 2] << 16) | + (record->data[index_data + 3] << 24); + data[1] = record->data[index_data + 4]; + + link_desc = (struct fru_picmgext_amc_link_desc_record *) &data[0]; - printf(" AMC Link Descriptor:\n" ); + printf(" AMC Link Descriptor:\n" ); - printf("\t- Link Type: %s \n", - val2str (link_desc->type, ipmi_ekanalyzer_link_type)); - switch ( link_desc->type ){ + printf("\t- Link Type: %s \n", + val2str (link_desc->type, ipmi_ekanalyzer_link_type)); + switch ( link_desc->type ) { case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE: case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS1: case FRU_PICMGEXT_AMC_LINK_TYPE_PCIE_AS2: @@ -3647,14 +3685,14 @@ ipmi_ek_display_amc_p2p_record( struct ipmi_ek_multi_header * record ) printf("\t- Link Group ID: %d \n", link_desc->group_id ); printf("\t- Link Asym. Match: %i\n", link_desc->asym_match); break; - } - printf("\t- AMC Link Designator:\n"); - printf("\t Channel ID: %i\n", link_desc->channel_id); - printf("\t\t Lane 0: %s\n", (link_desc->port_flag_0)?"enable":"disable"); - printf("\t\t Lane 1: %s\n", (link_desc->port_flag_1)?"enable":"disable"); - printf("\t\t Lane 2: %s\n", (link_desc->port_flag_2)?"enable":"disable"); - printf("\t\t Lane 3: %s\n", (link_desc->port_flag_3)?"enable":"disable"); - index_data += sizeof (struct fru_picmgext_amc_link_desc_record); + } + printf("\t- AMC Link Designator:\n"); + printf("\t Channel ID: %i\n", link_desc->channel_id); + printf("\t\t Lane 0: %s\n", (link_desc->port_flag_0)?"enable":"disable"); + printf("\t\t Lane 1: %s\n", (link_desc->port_flag_1)?"enable":"disable"); + printf("\t\t Lane 2: %s\n", (link_desc->port_flag_2)?"enable":"disable"); + printf("\t\t Lane 3: %s\n", (link_desc->port_flag_3)?"enable":"disable"); + index_data += FRU_PICMGEXT_AMC_LINK_DESC_RECORD_SIZE; } } -- 1.7.7 ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar _______________________________________________ Ipmitool-devel mailing list Ipmitool-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ipmitool-devel