File librtas.LE_support_for_SRC-FRU_events.patch of Package librtas.156
commit ac0a91d2730740cd279d80ccd4c83b0a04827d1d
Author: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Date: Fri Oct 17 10:10:29 2014 -0400
LE Support for SRC/FRU events
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
diff --git a/librtasevent_src/librtasevent_v6.h b/librtasevent_src/librtasevent_v6.h
index 7fdcb17..7097bb0 100644
--- a/librtasevent_src/librtasevent_v6.h
+++ b/librtasevent_src/librtasevent_v6.h
@@ -267,9 +267,15 @@ struct rtas_lri_scn_raw {
struct rtas_fru_hdr {
struct rtas_fru_hdr *next;
char id[2];
+ uint32_t length;
+ uint32_t flags;
+};
+
+struct rtas_fru_hdr_raw {
+ char id[2];
uint32_t length:8;
uint32_t flags:8;
-};
+}__attribute__((__packed__));
#define RE_FRU_HDR_SZ 4
#define RE_FRU_HDR_OFFSET(x) ((char *)(x) + sizeof(struct rtas_fru_hdr *))
@@ -307,6 +313,16 @@ struct rtas_fru_id_scn {
char serial_no[13];
};
+struct rtas_fru_id_scn_raw {
+ struct rtas_fru_hdr_raw fruhdr;
+
+ /* The following fields may not be present */
+ char part_no[8];
+ char procedure_id[8];
+ char ccin[5];
+ char serial_no[13];
+}__attribute__((__packed__));
+
/**
* @struct rtas_fru_pe_scn
* @brief contents of the FRU Power Enclosure Substructure
@@ -317,11 +333,22 @@ struct rtas_fru_pe_scn {
char pce_name[32];
};
+struct rtas_fru_pe_scn_raw {
+ struct rtas_fru_hdr_raw fruhdr;
+ struct rtas_mtms pce_mtms;
+ char pce_name[32];
+}__attribute__((__packed__));
+
/**
* @struct fru_mru
* @brief FRU MR Description structs
*/
struct fru_mru {
+ char priority;
+ uint32_t id;
+};
+
+struct fru_mru_raw {
uint32_t /* reserved */:24;
char priority;
uint32_t id;
@@ -339,18 +366,24 @@ struct rtas_fru_mr_scn {
uint32_t /* reserved */:32;
struct fru_mru mrus[15];
};
+
+struct rtas_fru_mr_scn_raw {
+ struct rtas_fru_hdr_raw fruhdr;
+ uint32_t /* reserved */:32;
+ struct fru_mru_raw mrus[15];
+};
/**
* @struct rtas_v6_fru_scn
* @brief RTAS version 6 FRU callout section
*/
struct rtas_fru_scn {
- uint32_t length:8; /**< call-out length */
- uint32_t type:4; /**< callout type */
- uint32_t fru_id_included:1; /**< fru id subsection included */
- uint32_t fru_subscn_included:3;
+ uint32_t length; /**< call-out length */
+ uint32_t type; /**< callout type */
+ uint32_t fru_id_included; /**< fru id subsection included */
+ uint32_t fru_subscn_included;
- char priority; /**< fru priority */
+ char priority; /**< fru priority */
#define RTAS_FRU_PRIORITY_HIGH 'H'
#define RTAS_FRU_PRIORITY_MEDIUM 'M'
#define RTAS_FRU_PRIORITY_MEDIUM_A 'A'
@@ -358,12 +391,20 @@ struct rtas_fru_scn {
#define RTAS_FRU_PRIORITY_MEDIUM_C 'C'
#define RTAS_FRU_PRIORITY_LOW 'L'
- uint32_t loc_code_length:8; /**< location field length */
- char loc_code[80]; /**< location code */
+ uint32_t loc_code_length; /**< location field length */
+ char loc_code[80]; /**< location code */
struct rtas_fru_scn *next;
struct rtas_fru_hdr *subscns;
};
+struct rtas_fru_scn_raw {
+ uint32_t length:8;
+ uint32_t data1:8;
+ char priority;
+ uint32_t loc_code_length:8;
+ char loc_code[80];
+};
+
#define RE_FRU_SCN_SZ 4
/**
@@ -372,31 +413,54 @@ struct rtas_fru_scn {
*/
struct rtas_src_scn {
struct scn_header shdr;
- struct rtas_v6_hdr_raw v6hdr;
+ struct rtas_v6_hdr v6hdr;
- uint32_t version:8; /**< SRC version */
- char src_platform_data[7]; /**< platform specific data */
+ uint32_t version; /**< SRC version */
+ char src_platform_data[7]; /**< platform specific data */
#define src_subscns_included(src) ((src)->src_platform_data[0] & 0x01)
- uint32_t ext_refcode2:32; /**< extended reference code word 2 */
- uint32_t ext_refcode3:32; /**< extended reference code word 3 */
- uint32_t ext_refcode4:32; /**< extended reference code word 4 */
- uint32_t ext_refcode5:32; /**< extended reference code word 5 */
+ uint32_t ext_refcode2; /**< extended reference code word 2 */
+ uint32_t ext_refcode3; /**< extended reference code word 3 */
+ uint32_t ext_refcode4; /**< extended reference code word 4 */
+ uint32_t ext_refcode5; /**< extended reference code word 5 */
- uint32_t ext_refcode6:32; /**< extended reference code word 6 */
- uint32_t ext_refcode7:32; /**< extended reference code word 7 */
- uint32_t ext_refcode8:32; /**< extended reference code word 8 */
- uint32_t ext_refcode9:32; /**< extended reference code word 9 */
+ uint32_t ext_refcode6; /**< extended reference code word 6 */
+ uint32_t ext_refcode7; /**< extended reference code word 7 */
+ uint32_t ext_refcode8; /**< extended reference code word 8 */
+ uint32_t ext_refcode9; /**< extended reference code word 9 */
- char primary_refcode[36];/**< primary reference code */
+ char primary_refcode[36]; /**< primary reference code */
- uint32_t subscn_id:8; /**< sub-section id (0xC0) */
- uint32_t subscn_platform_data:8; /**< platform specific data */
- uint32_t subscn_length:16; /**< sub-section length */
+ uint32_t subscn_id; /**< sub-section id (0xC0) */
+ uint32_t subscn_platform_data; /**< platform specific data */
+ uint32_t subscn_length; /**< sub-section length */
struct rtas_fru_scn *fru_scns;
};
+struct rtas_src_scn_raw {
+ struct rtas_v6_hdr_raw v6hdr;
+
+ uint32_t version:8;
+ char src_platform_data[7];
+
+ uint32_t ext_refcode2:32;
+ uint32_t ext_refcode3:32;
+ uint32_t ext_refcode4:32;
+ uint32_t ext_refcode5:32;
+
+ uint32_t ext_refcode6:32;
+ uint32_t ext_refcode7:32;
+ uint32_t ext_refcode8:32;
+ uint32_t ext_refcode9:32;
+
+ char primary_refcode[36];
+
+ uint32_t subscn_id:8;
+ uint32_t subscn_platform_data:8;
+ uint32_t subscn_length:16;
+};
+
#define RE_SRC_SCN_SZ 80
#define RE_SRC_SUBSCN_SZ 4
diff --git a/librtasevent_src/rtas_srcfru.c b/librtasevent_src/rtas_srcfru.c
index c757999..1fb1840 100644
--- a/librtasevent_src/rtas_srcfru.c
+++ b/librtasevent_src/rtas_srcfru.c
@@ -19,6 +19,23 @@
#include "rtas_src_codes.c"
/**
+ * parse_fru_hdr
+ * @brief Parse the ontents of a FRU header
+ *
+ * @param fru_hdr rtas_fru_hdr pointer
+ * @param fru_hdr_raw rtas_fru_hdr_raw pointer
+ */
+static void parse_fru_hdr(struct rtas_fru_hdr *fru_hdr,
+ struct rtas_fru_hdr_raw *fru_hdr_raw)
+{
+ fru_hdr->id[0] = fru_hdr_raw->id[0];
+ fru_hdr->id[1] = fru_hdr_raw->id[1];
+
+ fru_hdr->length = fru_hdr_raw->length;
+ fru_hdr->flags = fru_hdr_raw->flags;
+}
+
+/**
* parse_fru_id_scn
* @brief Parse a FRU Identity Substructure
*
@@ -29,6 +46,7 @@ static struct rtas_fru_hdr *
parse_fru_id_scn(struct rtas_event *re)
{
struct rtas_fru_id_scn *fru_id;
+ struct rtas_fru_id_scn_raw *fru_id_raw;
fru_id = malloc(sizeof(*fru_id));
if (fru_id == NULL) {
@@ -37,7 +55,10 @@ parse_fru_id_scn(struct rtas_event *re)
}
memset(fru_id, 0, sizeof(*fru_id));
- rtas_copy(RE_FRU_HDR_OFFSET(fru_id), re, RE_FRU_HDR_SZ);
+
+ fru_id_raw = (struct rtas_fru_id_scn_raw *)re->buffer + re->offset;
+ parse_fru_hdr(&fru_id->fruhdr, &fru_id_raw->fruhdr);
+ re->offset += RE_FRU_HDR_SZ;
if (fruid_has_part_no(fru_id)) {
strcpy(fru_id->part_no, RE_EVENT_OFFSET(re));
@@ -73,6 +94,7 @@ static struct rtas_fru_hdr *
parse_fru_pe_scn(struct rtas_event *re)
{
struct rtas_fru_pe_scn *fru_pe;
+ struct rtas_fru_pe_scn_raw *fru_pe_raw;
uint32_t scn_sz;
char *data;
@@ -83,7 +105,9 @@ parse_fru_pe_scn(struct rtas_event *re)
}
memset(fru_pe, 0, sizeof(*fru_pe));
- rtas_copy(RE_FRU_HDR_OFFSET(fru_pe), re, RE_FRU_HDR_SZ);
+ fru_pe_raw = (struct rtas_fru_pe_scn_raw *)re->buffer + re->offset;
+ parse_fru_hdr(&fru_pe->fruhdr, &fru_pe_raw->fruhdr);
+ re->offset += RE_FRU_HDR_SZ;
scn_sz = fru_pe->fruhdr.length;
data = (char *)fru_pe + sizeof(fru_pe->fruhdr);
@@ -104,8 +128,8 @@ static struct rtas_fru_hdr *
parse_fru_mr_scn(struct rtas_event *re)
{
struct rtas_fru_mr_scn *fru_mr;
- uint32_t scn_sz;
- char *data;
+ struct rtas_fru_mr_scn_raw *fru_mr_raw;
+ int i, mrus_sz, num_mrus;
fru_mr = malloc(sizeof(*fru_mr));
if (fru_mr == NULL) {
@@ -114,16 +138,39 @@ parse_fru_mr_scn(struct rtas_event *re)
}
memset(fru_mr, 0, sizeof(*fru_mr));
- rtas_copy(RE_FRU_HDR_OFFSET(fru_mr), re, RE_FRU_HDR_SZ);
+ fru_mr_raw = (struct rtas_fru_mr_scn_raw *)re->buffer + re->offset;
+ parse_fru_hdr(&fru_mr->fruhdr, &fru_mr_raw->fruhdr);
+ re->offset += RE_FRU_HDR_SZ;
- scn_sz = fru_mr->fruhdr.length;
- data = (char *)fru_mr + sizeof(fru_mr->fruhdr);
-
- rtas_copy(data, re, scn_sz - RE_FRU_HDR_SZ);
+ mrus_sz = fru_mr->fruhdr.length - RE_FRU_HDR_SZ - sizeof(uint32_t);
+ num_mrus = mrus_sz / sizeof(struct fru_mru_raw);
+
+ for (i = 0; i < num_mrus; i++) {
+ fru_mr->mrus[i].priority = fru_mr_raw->mrus[i].priority;
+ fru_mr->mrus[i].id = be32toh(fru_mr_raw->mrus[i].id);
+ }
+ re->offset += mrus_sz + sizeof(uint32_t) /* reserved piece */;
return (struct rtas_fru_hdr *)fru_mr;
}
+void parse_fru_scn(struct rtas_event *re, struct rtas_fru_scn *fru,
+ struct rtas_fru_scn_raw *rawfru)
+{
+ fru->length = rawfru->length;
+
+ fru->type = (rawfru->data1 & 0xf0) >> 4;
+ fru->fru_id_included = (rawfru->data1 & 0x08) >> 3;
+ fru->fru_subscn_included = rawfru->data1 & 0x07;
+
+ fru->priority = rawfru->priority;
+ fru->loc_code_length = rawfru->loc_code_length;
+ re->offset += RE_FRU_SCN_SZ;
+
+ memcpy(fru->loc_code, rawfru->loc_code, fru->loc_code_length);
+ re->offset += fru->loc_code_length;
+}
+
/**
* parse_v6_src_scn
* @brief parse a version 6 rtas SRC section
@@ -136,6 +183,7 @@ int
parse_src_scn(struct rtas_event *re)
{
struct rtas_src_scn *src;
+ struct rtas_src_scn_raw *src_raw;
struct rtas_fru_scn *fru, *last_fru;
int total_len, srcsub_len;
@@ -148,13 +196,36 @@ parse_src_scn(struct rtas_event *re)
memset(src, 0, sizeof(*src));
src->shdr.raw_offset = re->offset;
- rtas_copy(RE_SHDR_OFFSET(src), re, RE_SRC_SCN_SZ);
- add_re_scn(re, src, re_scn_id(&src->v6hdr));
+ src_raw = (struct rtas_src_scn_raw *)(re->buffer + re->offset);
+ parse_v6_hdr(&src->v6hdr, &src_raw->v6hdr);
- if (! src_subscns_included(src))
+ src->version = src_raw->version;
+ memcpy(&src->src_platform_data, &src_raw->src_platform_data,
+ sizeof(src->src_platform_data));
+
+ src->ext_refcode2 = be32toh(src_raw->ext_refcode2);
+ src->ext_refcode3 = be32toh(src_raw->ext_refcode3);
+ src->ext_refcode4 = be32toh(src_raw->ext_refcode4);
+ src->ext_refcode5 = be32toh(src_raw->ext_refcode5);
+
+ src->ext_refcode6 = be32toh(src_raw->ext_refcode6);
+ src->ext_refcode7 = be32toh(src_raw->ext_refcode7);
+ src->ext_refcode8 = be32toh(src_raw->ext_refcode8);
+ src->ext_refcode9 = be32toh(src_raw->ext_refcode9);
+
+ memcpy(&src->primary_refcode, &src_raw->primary_refcode,
+ sizeof(src->primary_refcode));
+
+ re->offset += RE_SRC_SCN_SZ;
+ add_re_scn(re, src, re_scn_id(&src_raw->v6hdr));
+
+ if (!src_subscns_included(src))
return 0;
- rtas_copy(RE_SHDR_OFFSET(src) + RE_SRC_SCN_SZ + 4, re, RE_SRC_SUBSCN_SZ);
+ src->subscn_id = src_raw->subscn_id;
+ src->subscn_platform_data = src_raw->subscn_platform_data;
+ src->subscn_length = be16toh(src_raw->subscn_length);
+ re->offset += RE_SRC_SUBSCN_SZ;
srcsub_len = src->subscn_length * 4; /*get number of bytes */
total_len = RE_SRC_SUBSCN_SZ;
@@ -164,6 +235,7 @@ parse_src_scn(struct rtas_event *re)
do {
uint32_t fru_len, fru_end;
struct rtas_fru_hdr *last_fruhdr = NULL;
+ struct rtas_fru_scn_raw *rawfru;
fru = malloc(sizeof(*fru));
if (fru == NULL) {
@@ -174,11 +246,8 @@ parse_src_scn(struct rtas_event *re)
memset(fru, 0, sizeof(*fru));
- /* First the fixed part of the fru */
- rtas_copy(fru, re, RE_FRU_SCN_SZ);
-
- /* Then the variable length location string */
- rtas_copy(fru->loc_code, re, fru->loc_code_length);
+ rawfru = (struct rtas_fru_scn_raw *)(re->buffer + re->offset);
+ parse_fru_scn(re, fru, rawfru);
fru_len = RE_FRU_SCN_SZ + fru->loc_code_length;
fru_end = re->offset + fru->length - fru_len;