src/sg_ses.c
static int
populate_type_desc_hdr_arr(int fd, struct type_desc_hdr_t * tdhp,
                           uint32_t * generationp,
                           struct enclosure_info * primary_ip,
                           struct opts_t * op)
{
    int resp_len, k, el, num_subs, sum_type_dheaders, res, n;
    int ret = 0;
    uint32_t gen_code;
    unsigned char * resp;
    const unsigned char * ucp;
    const unsigned char * last_ucp;

    resp = (unsigned char *)calloc(op->maxlen, 1);
    if (NULL == resp) {
        pr2serr("populate: unable to allocate %d bytes on heap\n",
                op->maxlen);
        ret = -1;
        goto the_end;
    }
    res = do_rec_diag(fd, DPC_CONFIGURATION, resp, op->maxlen, op, &resp_len);
    if (res) {
        pr2serr("populate: couldn't read config page, res=%d\n", res);
        ret = -1;
        goto the_end;
    }
    if (resp_len < 4) {
        ret = -1;
        goto the_end;
    }
    num_subs = resp[1] + 1;
    sum_type_dheaders = 0;
    last_ucp = resp + resp_len - 1;
    gen_code = sg_get_unaligned_be32(resp + 4);
    if (generationp)
        *generationp = gen_code;
    ucp = resp + 8;
    for (k = 0; k < num_subs; ++k, ucp += el) {
        if ((ucp + 3) > last_ucp)
            goto p_truncated;
        el = ucp[3] + 4;
        sum_type_dheaders += ucp[2];
        if (el < 40) {
            pr2serr("populate: short enc descriptor len=%d ??\n", el);
            continue;
        }
        if ((0 == k) && primary_ip) {
            ++primary_ip->have_info;
            primary_ip->rel_esp_id = (ucp[0] & 0x70) >> 4;
            primary_ip->num_esp = (ucp[0] & 0x7);
            memcpy(primary_ip->enc_log_id, ucp + 4, 8);
            memcpy(primary_ip->enc_vendor_id, ucp + 12, 8);
            memcpy(primary_ip->product_id, ucp + 20, 16);
            memcpy(primary_ip->product_rev_level, ucp + 36, 4);
        }
    }
    for (k = 0; k < sum_type_dheaders; ++k, ucp += 4) {
        if ((ucp + 3) > last_ucp)
            goto p_truncated;
        if (k >= MX_ELEM_HDR) {
            pr2serr("populate: too many elements\n");
            ret = -1;
            goto the_end;
        }
        tdhp[k].etype = ucp[0];
        tdhp[k].num_elements = ucp[1];
        tdhp[k].se_id = ucp[2];
        tdhp[k].txt_len = ucp[3];
    }
    if (op->ind_given && op->ind_etp) {
        n = op->ind_et_inst;
        for (k = 0; k < sum_type_dheaders; ++k) {
            if (op->ind_etp->elem_type_code == tdhp[k].etype) {
                if (0 == n)
                    break;
                else
                    --n;
            }
        }
        if (k < sum_type_dheaders)
            op->ind_th = k;
        else {
            if (op->ind_et_inst)
                pr2serr("populate: unable to find element type '%s%d'\n",
                        op->ind_etp->abbrev, op->ind_et_inst);
            else
                pr2serr("populate: unable to find element type '%s'\n",
                        op->ind_etp->abbrev);
            ret = -1;
            goto the_end;
        }
    }
    ret = sum_type_dheaders;
    goto the_end;

p_truncated:
    pr2serr("populate: config too short\n");
    ret = -1;

the_end:
    if (resp)
        free(resp);
    return ret;
}
/* DPC_CONFIGURATION
 * Returns total number of type descriptor headers written to 'tdhp' or -1
 * if there is a problem */
DPC_CONFIGURATION
Returns total number of type descriptor headers written to 'tdhp' or -1
if there is a problem
DPC_CONFIGURATION Returns total number of type descriptor headers written to ' tdhp ' or - 1 if there is a problem
static int
populate_type_desc_hdr_arr(int fd, struct type_desc_hdr_t * tdhp,
                           uint32_t * generationp,
                           struct enclosure_info * primary_ip,
                           struct opts_t * op)
{
    int resp_len, k, el, num_subs, sum_type_dheaders, res, n;
    int ret = 0;
    uint32_t gen_code;
    unsigned char * resp;
    const unsigned char * ucp;
    const unsigned char * last_ucp;
    resp = (unsigned char *)calloc(op->maxlen, 1);
    if (NULL == resp) {
        pr2serr("populate: unable to allocate %d bytes on heap\n",
                op->maxlen);
        ret = -1;
        goto the_end;
    }
    res = do_rec_diag(fd, DPC_CONFIGURATION, resp, op->maxlen, op, &resp_len);
    if (res) {
        pr2serr("populate: couldn't read config page, res=%d\n", res);
        ret = -1;
        goto the_end;
    }
    if (resp_len < 4) {
        ret = -1;
        goto the_end;
    }
    num_subs = resp[1] + 1;
    sum_type_dheaders = 0;
    last_ucp = resp + resp_len - 1;
    gen_code = sg_get_unaligned_be32(resp + 4);
    if (generationp)
        *generationp = gen_code;
    ucp = resp + 8;
    for (k = 0; k < num_subs; ++k, ucp += el) {
        if ((ucp + 3) > last_ucp)
            goto p_truncated;
        el = ucp[3] + 4;
        sum_type_dheaders += ucp[2];
        if (el < 40) {
            pr2serr("populate: short enc descriptor len=%d ??\n", el);
            continue;
        }
        if ((0 == k) && primary_ip) {
            ++primary_ip->have_info;
            primary_ip->rel_esp_id = (ucp[0] & 0x70) >> 4;
            primary_ip->num_esp = (ucp[0] & 0x7);
            memcpy(primary_ip->enc_log_id, ucp + 4, 8);
            memcpy(primary_ip->enc_vendor_id, ucp + 12, 8);
            memcpy(primary_ip->product_id, ucp + 20, 16);
            memcpy(primary_ip->product_rev_level, ucp + 36, 4);
        }
    }
    for (k = 0; k < sum_type_dheaders; ++k, ucp += 4) {
        if ((ucp + 3) > last_ucp)
            goto p_truncated;
        if (k >= MX_ELEM_HDR) {
            pr2serr("populate: too many elements\n");
            ret = -1;
            goto the_end;
        }
        tdhp[k].etype = ucp[0];
        tdhp[k].num_elements = ucp[1];
        tdhp[k].se_id = ucp[2];
        tdhp[k].txt_len = ucp[3];
    }
    if (op->ind_given && op->ind_etp) {
        n = op->ind_et_inst;
        for (k = 0; k < sum_type_dheaders; ++k) {
            if (op->ind_etp->elem_type_code == tdhp[k].etype) {
                if (0 == n)
                    break;
                else
                    --n;
            }
        }
        if (k < sum_type_dheaders)
            op->ind_th = k;
        else {
            if (op->ind_et_inst)
                pr2serr("populate: unable to find element type '%s%d'\n",
                        op->ind_etp->abbrev, op->ind_et_inst);
            else
                pr2serr("populate: unable to find element type '%s'\n",
                        op->ind_etp->abbrev);
            ret = -1;
            goto the_end;
        }
    }
    ret = sum_type_dheaders;
    goto the_end;
p_truncated:
    pr2serr("populate: config too short\n");
    ret = -1;
the_end:
    if (resp)
        free(resp);
    return ret;
}
static int populate_type_desc_hdr_arr ( int fd , struct type_desc_hdr_t * tdhp , uint32_t * generationp , struct enclosure_info * primary_ip , struct opts_t * op ) { int resp_len , k , el , num_subs , sum_type_dheaders , res , n ; int ret = 0 ; uint32_t gen_code ; unsigned char * resp ; const unsigned char * ucp ; const unsigned char * last_ucp ; resp = ( unsigned char * ) calloc ( op -> maxlen , 1 ) ; if ( NULL == resp ) { pr2serr ( " \n " , op -> maxlen ) ; ret = -1 ; goto the_end ; } res = do_rec_diag ( fd , DPC_CONFIGURATION , resp , op -> maxlen , op , & resp_len ) ; if ( res ) { pr2serr ( " \n " , res ) ; ret = -1 ; goto the_end ; } if ( resp_len < 4 ) { ret = -1 ; goto the_end ; } num_subs = resp [ 1 ] + 1 ; sum_type_dheaders = 0 ; last_ucp = resp + resp_len - 1 ; gen_code = sg_get_unaligned_be32 ( resp + 4 ) ; if ( generationp ) * generationp = gen_code ; ucp = resp + 8 ; for ( k = 0 ; k < num_subs ; ++ k , ucp += el ) { if ( ( ucp + 3 ) > last_ucp ) goto p_truncated ; el = ucp [ 3 ] + 4 ; sum_type_dheaders += ucp [ 2 ] ; if ( el < 40 ) { pr2serr ( " \n " , el ) ; continue ; } if ( ( 0 == k ) && primary_ip ) { ++ primary_ip -> have_info ; primary_ip -> rel_esp_id = ( ucp [ 0 ] & 0x70 ) >> 4 ; primary_ip -> num_esp = ( ucp [ 0 ] & 0x7 ) ; memcpy ( primary_ip -> enc_log_id , ucp + 4 , 8 ) ; memcpy ( primary_ip -> enc_vendor_id , ucp + 12 , 8 ) ; memcpy ( primary_ip -> product_id , ucp + 20 , 16 ) ; memcpy ( primary_ip -> product_rev_level , ucp + 36 , 4 ) ; } } for ( k = 0 ; k < sum_type_dheaders ; ++ k , ucp += 4 ) { if ( ( ucp + 3 ) > last_ucp ) goto p_truncated ; if ( k >= MX_ELEM_HDR ) { pr2serr ( " \n " ) ; ret = -1 ; goto the_end ; } tdhp [ k ] . etype = ucp [ 0 ] ; tdhp [ k ] . num_elements = ucp [ 1 ] ; tdhp [ k ] . se_id = ucp [ 2 ] ; tdhp [ k ] . txt_len = ucp [ 3 ] ; } if ( op -> ind_given && op -> ind_etp ) { n = op -> ind_et_inst ; for ( k = 0 ; k < sum_type_dheaders ; ++ k ) { if ( op -> ind_etp -> elem_type_code == tdhp [ k ] . etype ) { if ( 0 == n ) break ; else -- n ; } } if ( k < sum_type_dheaders ) op -> ind_th = k ; else { if ( op -> ind_et_inst ) pr2serr ( " \n " , op -> ind_etp -> abbrev , op -> ind_et_inst ) ; else pr2serr ( " \n " , op -> ind_etp -> abbrev ) ; ret = -1 ; goto the_end ; } } ret = sum_type_dheaders ; goto the_end ; p_truncated : pr2serr ( " \n " ) ; ret = -1 ; the_end : if ( resp ) free ( resp ) ; return ret ; }
DPC_CONFIGURATION
 Returns total number of type descriptor headers written to 'tdhp' or -1
 if there is a problem
DPC_CONFIGURATION Returns total number of type descriptor headers written to ' tdhp ' or - 1 if there is a problem