Example #1
0
/**
 * parse_generic_v6_scn
 *
 */
int
parse_generic_v6_scn(struct rtas_event *re)
{
    struct rtas_v6_generic  *gen;
    uint32_t copy_sz = sizeof(struct rtas_v6_hdr);

    gen = malloc(sizeof(*gen));
    if (gen == NULL) {
        errno = ENOMEM;
        return -1;
    }

    memset(gen, 0, sizeof(*gen));
    gen->shdr.raw_offset = re->offset;

    rtas_copy(RE_SHDR_OFFSET(gen), re, copy_sz);
    
    if (gen->v6hdr.length > copy_sz) {
        uint32_t    data_sz = gen->v6hdr.length - copy_sz;
        gen->data = malloc(data_sz);
        if (gen->data == NULL) {
            errno = ENOMEM;
            return -1;
        }

        memset(gen->data, 0, data_sz);
        rtas_copy(gen->data, re, data_sz);
    }

    add_re_scn(re, gen, RTAS_GENERIC_SCN);
    return 0;
}
Example #2
0
/**
 * parse_vend_specific_scn
 *
 */
int
parse_vend_errlog_scn(struct rtas_event *re)
{
    struct rtas_vend_errlog *ve;

    ve = malloc(sizeof(*ve));
    if (ve == NULL) {
        errno = ENOMEM;
        return -1;
    }

    ve->shdr.raw_offset = re->offset;
    rtas_copy(RE_SHDR_OFFSET(ve), re, 4);

    /* See if there is additional data */
    ve->vendor_data_sz = re->event_length - re->offset;
    if (ve->vendor_data_sz > 0) {
        ve->vendor_data = malloc(ve->vendor_data_sz);
        if (ve->vendor_data == NULL) {
            errno = ENOMEM;
            return -1;
        }

        rtas_copy(ve->vendor_data, re, ve->vendor_data_sz);
    }
    
    add_re_scn(re, ve, RTAS_VEND_ERRLOG_SCN);
    return 0;
}
Example #3
0
/**
 * parse_mtms
 *
 */
void
parse_mtms(struct rtas_event *re, struct rtas_mtms *mtms)
{
    rtas_copy(mtms->model, re, 8);
    mtms->model[8] = '\0';

    rtas_copy(mtms->serial_no, re, 12);
    mtms->serial_no[12] = '\0';
}
Example #4
0
/**
 * parse_fru_pe_scn
 * @brief parse a FRU Power Enclosure Identity Substructure
 *
 * @param re rtas_event pointer
 * @returns pointer to parsed rtas_fru_pe_scn, NULL on failure
 */
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;

    fru_pe = malloc(sizeof(*fru_pe));
    if (fru_pe == NULL) {
        errno = ENOMEM;
        return NULL;
    }

    memset(fru_pe, 0, sizeof(*fru_pe));
    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);
    
    rtas_copy(data, re, scn_sz - RE_FRU_HDR_SZ);

    return (struct rtas_fru_hdr *)fru_pe;
}
Example #5
0
/**
 * parse_generic_v6_scn
 *
 */
int
parse_generic_v6_scn(struct rtas_event *re)
{
    struct rtas_v6_generic  *gen;
    struct rtas_v6_hdr_raw *rawhdr;

    gen = malloc(sizeof(*gen));
    if (gen == NULL) {
        errno = ENOMEM;
        return -1;
    }

    memset(gen, 0, sizeof(*gen));
    gen->shdr.raw_offset = re->offset;

    rawhdr = (struct rtas_v6_hdr_raw *)(re->buffer + re->offset);
    parse_v6_hdr(&gen->v6hdr, rawhdr);
    re->offset += RTAS_V6_HDR_SIZE;

    if (gen->v6hdr.length > RTAS_V6_HDR_SIZE) {
        uint32_t    data_sz = gen->v6hdr.length - RTAS_V6_HDR_SIZE;
        gen->data = malloc(data_sz);
        if (gen->data == NULL) {
            errno = ENOMEM;
            return -1;
        }

        memset(gen->data, 0, data_sz);
        rtas_copy(gen->data, re, data_sz);
    }

    add_re_scn(re, gen, RTAS_GENERIC_SCN);
    return 0;
}
Example #6
0
/**
 * parse_main_a_scn
 *
 */
int
parse_priv_hdr_scn(struct rtas_event *re)
{
    struct rtas_priv_hdr_scn *privhdr;

    privhdr = malloc(sizeof(*privhdr));
    if (privhdr == NULL) {
        errno = ENOMEM;
        return -1;
    }

    memset(privhdr, 0, sizeof(*privhdr));
    privhdr->shdr.raw_offset = re->offset;

    /* Copy up through the creator subsection id.  Sinc the subsection
     * id can be ascii we null terminate it then copy the stuff after it.
     */
    rtas_copy(RE_SHDR_OFFSET(privhdr), re, 48);

    /* If the creator id is 'E', the the subsystem version is in ascii,
     * copy this info to a null terminated string.
     */
    if (privhdr->creator_id == RTAS_PH_CREAT_SERVICE_PROC) {
        memcpy(privhdr->creator_subid_name, 
               &privhdr->creator_subid_hi, 8);
        privhdr->creator_subid_name[8] = '\0';
    }

    add_re_scn(re, privhdr, RTAS_PRIV_HDR_SCN);
    return 0;
}
Example #7
0
/**
 * parse_fru_id_scn
 * @brief Parse a FRU Identity Substructure
 *
 * @param re rtas_event pointer
 * @returns pointer to parsed rtas_fru_id_scn, NULL on failure
 */
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) {
        errno = ENOMEM;
        return NULL;
    }

    memset(fru_id, 0, sizeof(*fru_id));

    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));
        re->offset += 8;
    }

    if (fruid_has_proc_id(fru_id)) {
        strcpy(fru_id->procedure_id, RE_EVENT_OFFSET(re));
        re->offset += 8;
    }

    if (fruid_has_ccin(fru_id)) {
        rtas_copy(fru_id->ccin, re, 4);
        fru_id->ccin[4] = '\0';
    }
            
    if (fruid_has_serial_no(fru_id)) {
        rtas_copy(fru_id->serial_no, re, 12);
        fru_id->serial_no[12] = '\0';
    }

    return (struct rtas_fru_hdr *)fru_id;
}
Example #8
0
/**
 * parse_ibm diag_scn
 *
 */
int
parse_ibm_diag_scn(struct rtas_event *re)
{
    struct rtas_ibm_diag_scn *ibmdiag;

    ibmdiag = malloc(sizeof(*ibmdiag));
    if (ibmdiag == NULL) {
        errno = ENOMEM;
        return -1;
    }

    ibmdiag->shdr.raw_offset = re->offset;

    rtas_copy(RE_SHDR_OFFSET(ibmdiag), re, sizeof(uint32_t));
    add_re_scn(re, ibmdiag, RTAS_IBM_DIAG_SCN);

    return 0;
}
Example #9
0
/**
 * parse_cpu_scn
 *
 */
int
parse_cpu_scn(struct rtas_event *re)
{
    struct rtas_cpu_scn *cpu_scn;

    cpu_scn = malloc(sizeof(*cpu_scn));
    if (cpu_scn == NULL) {
        errno = ENOMEM;
        return -1;
    }

    cpu_scn->shdr.raw_offset = re->offset;

    rtas_copy(RE_SHDR_OFFSET(cpu_scn), re, RE_V4_SCN_SZ);
    add_re_scn(re, cpu_scn, RTAS_CPU_SCN);

    return 0;
}
Example #10
0
/**
 * parse_usr_hdr_scn
 *
 */
int
parse_usr_hdr_scn(struct rtas_event *re)
{
    struct rtas_usr_hdr_scn *usrhdr;

    usrhdr = malloc(sizeof(*usrhdr));
    if (usrhdr == NULL) {
        errno = ENOMEM;
        return -1;
    }

    memset(usrhdr, 0, sizeof(*usrhdr));
    usrhdr->shdr.raw_offset = re->offset;

    rtas_copy(RE_SHDR_OFFSET(usrhdr), re, RE_USR_HDR_SCN_SZ);
    add_re_scn(re, usrhdr, RTAS_USR_HDR_SCN);

    return 0;
}
Example #11
0
/**
 * parse_mt_scn
 *
 */
int
parse_mt_scn(struct rtas_event *re)
{
    struct rtas_mt_scn *mt;

    mt = malloc(sizeof(*mt));
    if (mt == NULL) {
        errno = ENOMEM;
        return -1;
    }

    memset(mt, 0, sizeof(*mt));
    mt->shdr.raw_offset = re->offset;
    rtas_copy(RE_SHDR_OFFSET(mt), re, sizeof(struct rtas_v6_hdr_raw));
    
    parse_mtms(re, &mt->mtms);
    add_re_scn(re, mt, RTAS_MT_SCN);

    return 0;
}
Example #12
0
/**
 * parse_v6_src_scn
 * @brief parse a version 6 rtas SRC section
 *
 * @param re rtas_event pointer
 * @param src_start pointer to beginning of SRC section
 * @return 0 on success, !0 on failure
 */
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;
    src = malloc(sizeof(*src));
    if (src == NULL) {
        errno = ENOMEM;
        return 1;
    }

    src_raw = malloc(sizeof(*src_raw));
    if (src_raw == NULL) {
        errno = ENOMEM;
        return 1;
    }
           
    memset(src, 0, sizeof(*src));
    memset(src_raw, 0, sizeof(*src_raw));
    src->shdr.raw_offset = re->offset;

    rtas_copy(src_raw, re, RE_SRC_SCN_SZ);
    parse_v6_hdr(&src->v6hdr, &src_raw->v6hdr);

    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));

    add_re_scn(re, src, re_scn_id(&src_raw->v6hdr));

    if (!src_subscns_included(src))
        return 0;

    rtas_copy( (char *) src_raw + 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);

    srcsub_len = src->subscn_length * 4; /*get number of bytes */
    total_len = RE_SRC_SUBSCN_SZ;

    last_fru = NULL;

    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) {
            cleanup_rtas_event(re);
            errno = ENOMEM;
            return 1;
        }

        memset(fru, 0, sizeof(*fru));

	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;

	while (re->offset < fru_end) {
	    struct rtas_fru_hdr *cur_fruhdr = NULL;
	    char *id = re->buffer + re->offset;

            if (strncmp(id, "ID", 2) == 0)
                cur_fruhdr = parse_fru_id_scn(re);
            else if (strncmp(id, "PE", 2) == 0)
                cur_fruhdr = parse_fru_pe_scn(re);
            else if (strncmp(id, "MR", 2) == 0)
                cur_fruhdr = parse_fru_mr_scn(re);
            else {
                re->offset++;
                continue;
            }

            if (cur_fruhdr == NULL) {
                cleanup_rtas_event(re);
                return -1;
            }

            if (last_fruhdr == NULL)
                fru->subscns = cur_fruhdr;
            else
                last_fruhdr->next = cur_fruhdr;

            last_fruhdr = cur_fruhdr;
        }

        if (last_fru == NULL) 
            src->fru_scns = fru;
        else 
            last_fru->next = fru;

        last_fru = fru;
        
        total_len += fru->length;
    } while (total_len < srcsub_len);

    return 0;
}
Example #13
0
/**
 * parse_rtas_event
 * @brief parse an rtas event creating a populated rtas_event structure
 *
 * @param buf buffer containing the binary RTAS event
 * @param buflen length of the buffer 'buf'
 * @return pointer to rtas_event
 */
struct rtas_event *
parse_rtas_event(char *buf, int buflen)
{
    struct rtas_event *re;
    struct rtas_event_hdr *re_hdr;
    struct rtas_event_exthdr *rex_hdr;
    int rc;

    re = malloc(sizeof(*re));
    if (re == NULL) {
        errno = ENOMEM;
        return NULL;
    }

    memset(re, 0, sizeof(*re));
    re->buffer = buf;
    re->event_no = -1;

    re_hdr = malloc(sizeof(*re_hdr));
    if (re_hdr == NULL) {
	    cleanup_rtas_event(re);
	    errno = ENOMEM;
	    return NULL;
    }

    rtas_copy(RE_SHDR_OFFSET(re_hdr), re, RE_EVENT_HDR_SZ);
    add_re_scn(re, re_hdr, RTAS_EVENT_HDR);

    /* Validate the length of the buffer passed in. */
    re->event_length = re_hdr->ext_log_length + RE_EVENT_HDR_SZ;
    if (re->event_length > buflen) {
        cleanup_rtas_event(re);
        return NULL;
    }

    re->version = re_hdr->version;

    if (re_hdr->extended == 0)
        return re;
    
    rex_hdr = malloc(sizeof(*rex_hdr));
    if (rex_hdr == NULL) {
        cleanup_rtas_event(re);
        errno = ENOMEM;
        return NULL;
    }

    rtas_copy(RE_SHDR_OFFSET(rex_hdr), re, RE_EXT_HDR_SZ);
    add_re_scn(re, rex_hdr, RTAS_EVENT_EXT_HDR);

    if (re_hdr->version == 6) 
        return parse_v6_rtas_event(re);


    switch (rex_hdr->format_type) {
        case RTAS_EXTHDR_FMT_CPU:
            rc = parse_cpu_scn(re);
	    break;

        case RTAS_EXTHDR_FMT_EPOW:
            rc = parse_epow_scn(re);
            break;

        case RTAS_EXTHDR_FMT_IBM_DIAG:
            rc = parse_ibm_diag_scn(re);
            break;

        case RTAS_EXTHDR_FMT_IO:
            rc = parse_io_scn(re);
            break;

        case RTAS_EXTHDR_FMT_MEMORY:
            rc = parse_mem_scn(re);
            break;
	
        case RTAS_EXTHDR_FMT_POST:
            rc = parse_post_scn(re);
            break;

        case RTAS_EXTHDR_FMT_IBM_SP:
            rc = parse_sp_scn(re);
	    break;

        case RTAS_EXTHDR_FMT_VEND_SPECIFIC_1:
        case RTAS_EXTHDR_FMT_VEND_SPECIFIC_2:
            rc = parse_vend_errlog_scn(re);
            break;
            
        default:
            errno = EFAULT;
            rc = -1;
            break;
    }

    if ((rc == 0) && (re->offset < re->event_length))  
        rc = parse_vend_errlog_scn(re);

    if (rc) {
        cleanup_rtas_event(re);
        re = NULL;
    }

    return re;
}