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

Reply via email to