1*6bbe0590SSundeep Panicker /* 2*6bbe0590SSundeep Panicker * CDDL HEADER START 3*6bbe0590SSundeep Panicker * 4*6bbe0590SSundeep Panicker * The contents of this file are subject to the terms of the 5*6bbe0590SSundeep Panicker * Common Development and Distribution License (the "License"). 6*6bbe0590SSundeep Panicker * You may not use this file except in compliance with the License. 7*6bbe0590SSundeep Panicker * 8*6bbe0590SSundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*6bbe0590SSundeep Panicker * or http://www.opensolaris.org/os/licensing. 10*6bbe0590SSundeep Panicker * See the License for the specific language governing permissions 11*6bbe0590SSundeep Panicker * and limitations under the License. 12*6bbe0590SSundeep Panicker * 13*6bbe0590SSundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each 14*6bbe0590SSundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*6bbe0590SSundeep Panicker * If applicable, add the following below this CDDL HEADER, with the 16*6bbe0590SSundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying 17*6bbe0590SSundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner] 18*6bbe0590SSundeep Panicker * 19*6bbe0590SSundeep Panicker * CDDL HEADER END 20*6bbe0590SSundeep Panicker */ 21*6bbe0590SSundeep Panicker 22*6bbe0590SSundeep Panicker /* 23*6bbe0590SSundeep Panicker * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*6bbe0590SSundeep Panicker * Use is subject to license terms. 25*6bbe0590SSundeep Panicker */ 26*6bbe0590SSundeep Panicker 27*6bbe0590SSundeep Panicker #include <stdio.h> 28*6bbe0590SSundeep Panicker #include <stdarg.h> 29*6bbe0590SSundeep Panicker #include <stdlib.h> 30*6bbe0590SSundeep Panicker #include <errno.h> 31*6bbe0590SSundeep Panicker #include <string.h> 32*6bbe0590SSundeep Panicker 33*6bbe0590SSundeep Panicker #include "fru_access_impl.h" 34*6bbe0590SSundeep Panicker 35*6bbe0590SSundeep Panicker #include "libfruds.h" 36*6bbe0590SSundeep Panicker #include "libfrup.h" 37*6bbe0590SSundeep Panicker #include "fru_access.h" 38*6bbe0590SSundeep Panicker #include "fruraw.h" 39*6bbe0590SSundeep Panicker 40*6bbe0590SSundeep Panicker 41*6bbe0590SSundeep Panicker raw_list_t *g_raw = NULL; 42*6bbe0590SSundeep Panicker 43*6bbe0590SSundeep Panicker 44*6bbe0590SSundeep Panicker /* ARGSUSED */ 45*6bbe0590SSundeep Panicker static raw_list_t * 46*6bbe0590SSundeep Panicker treehdl_to_rawlist(fru_treehdl_t handle) 47*6bbe0590SSundeep Panicker { 48*6bbe0590SSundeep Panicker return (g_raw); 49*6bbe0590SSundeep Panicker } 50*6bbe0590SSundeep Panicker 51*6bbe0590SSundeep Panicker 52*6bbe0590SSundeep Panicker static container_hdl_t 53*6bbe0590SSundeep Panicker treehdl_to_conthdl(fru_treehdl_t handle) 54*6bbe0590SSundeep Panicker { 55*6bbe0590SSundeep Panicker raw_list_t *ptr; 56*6bbe0590SSundeep Panicker 57*6bbe0590SSundeep Panicker ptr = treehdl_to_rawlist(handle); 58*6bbe0590SSundeep Panicker if (ptr == NULL) { 59*6bbe0590SSundeep Panicker return (-1); 60*6bbe0590SSundeep Panicker } 61*6bbe0590SSundeep Panicker 62*6bbe0590SSundeep Panicker return (ptr->cont); 63*6bbe0590SSundeep Panicker } 64*6bbe0590SSundeep Panicker 65*6bbe0590SSundeep Panicker 66*6bbe0590SSundeep Panicker static fru_errno_t 67*6bbe0590SSundeep Panicker map_errno(int err) 68*6bbe0590SSundeep Panicker { 69*6bbe0590SSundeep Panicker switch (err) { 70*6bbe0590SSundeep Panicker case ENFILE: 71*6bbe0590SSundeep Panicker case EEXIST: 72*6bbe0590SSundeep Panicker return (FRU_DUPSEG); 73*6bbe0590SSundeep Panicker case EAGAIN: 74*6bbe0590SSundeep Panicker return (FRU_NOSPACE); 75*6bbe0590SSundeep Panicker case EPERM: 76*6bbe0590SSundeep Panicker return (FRU_INVALPERM); 77*6bbe0590SSundeep Panicker default : 78*6bbe0590SSundeep Panicker return (FRU_IOERROR); 79*6bbe0590SSundeep Panicker } 80*6bbe0590SSundeep Panicker } 81*6bbe0590SSundeep Panicker 82*6bbe0590SSundeep Panicker 83*6bbe0590SSundeep Panicker static raw_list_t * 84*6bbe0590SSundeep Panicker make_raw(uint8_t *buffer, size_t size, char *cont_type) 85*6bbe0590SSundeep Panicker { 86*6bbe0590SSundeep Panicker raw_list_t *node; 87*6bbe0590SSundeep Panicker 88*6bbe0590SSundeep Panicker node = (raw_list_t *)malloc(sizeof (raw_list_t)); 89*6bbe0590SSundeep Panicker if (node == NULL) { 90*6bbe0590SSundeep Panicker return (NULL); 91*6bbe0590SSundeep Panicker } 92*6bbe0590SSundeep Panicker 93*6bbe0590SSundeep Panicker node->hdl = 0; 94*6bbe0590SSundeep Panicker node->raw = buffer; 95*6bbe0590SSundeep Panicker node->size = size; 96*6bbe0590SSundeep Panicker node->cont_type = strdup(cont_type); 97*6bbe0590SSundeep Panicker if (node->cont_type == NULL) { 98*6bbe0590SSundeep Panicker free(node); 99*6bbe0590SSundeep Panicker return (NULL); 100*6bbe0590SSundeep Panicker } 101*6bbe0590SSundeep Panicker node->segs = NULL; 102*6bbe0590SSundeep Panicker 103*6bbe0590SSundeep Panicker return (node); 104*6bbe0590SSundeep Panicker } 105*6bbe0590SSundeep Panicker 106*6bbe0590SSundeep Panicker 107*6bbe0590SSundeep Panicker /* 108*6bbe0590SSundeep Panicker * Arguments : 109*6bbe0590SSundeep Panicker * 0 - pointer to byte buffer (in) 110*6bbe0590SSundeep Panicker * 1 - size of buffer (in) 111*6bbe0590SSundeep Panicker * 2 - container type, string (in) 112*6bbe0590SSundeep Panicker */ 113*6bbe0590SSundeep Panicker static fru_errno_t 114*6bbe0590SSundeep Panicker frt_initialize(int num, char **args) 115*6bbe0590SSundeep Panicker { 116*6bbe0590SSundeep Panicker 117*6bbe0590SSundeep Panicker 118*6bbe0590SSundeep Panicker if (num != 3) { 119*6bbe0590SSundeep Panicker return (FRU_FAILURE); 120*6bbe0590SSundeep Panicker } 121*6bbe0590SSundeep Panicker 122*6bbe0590SSundeep Panicker g_raw = make_raw((uint8_t *)args[0], (size_t)args[1], args[2]); 123*6bbe0590SSundeep Panicker if (g_raw == NULL) { 124*6bbe0590SSundeep Panicker return (FRU_FAILURE); 125*6bbe0590SSundeep Panicker } 126*6bbe0590SSundeep Panicker 127*6bbe0590SSundeep Panicker g_raw->cont = open_raw_data(g_raw); 128*6bbe0590SSundeep Panicker if (g_raw->cont == NULL) { 129*6bbe0590SSundeep Panicker return (FRU_FAILURE); 130*6bbe0590SSundeep Panicker } 131*6bbe0590SSundeep Panicker 132*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 133*6bbe0590SSundeep Panicker } 134*6bbe0590SSundeep Panicker 135*6bbe0590SSundeep Panicker 136*6bbe0590SSundeep Panicker static fru_errno_t 137*6bbe0590SSundeep Panicker frt_shutdown(void) 138*6bbe0590SSundeep Panicker { 139*6bbe0590SSundeep Panicker segment_list_t *lptr, *lptr2; 140*6bbe0590SSundeep Panicker 141*6bbe0590SSundeep Panicker (void) fru_close_container(g_raw->cont); 142*6bbe0590SSundeep Panicker free(g_raw->cont_type); 143*6bbe0590SSundeep Panicker lptr = g_raw->segs; 144*6bbe0590SSundeep Panicker while (lptr) { 145*6bbe0590SSundeep Panicker lptr2 = lptr; 146*6bbe0590SSundeep Panicker lptr = lptr->next; 147*6bbe0590SSundeep Panicker free(lptr2); 148*6bbe0590SSundeep Panicker } 149*6bbe0590SSundeep Panicker g_raw = NULL; 150*6bbe0590SSundeep Panicker 151*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 152*6bbe0590SSundeep Panicker } 153*6bbe0590SSundeep Panicker 154*6bbe0590SSundeep Panicker 155*6bbe0590SSundeep Panicker static fru_errno_t 156*6bbe0590SSundeep Panicker frt_get_root(fru_treehdl_t *node) 157*6bbe0590SSundeep Panicker { 158*6bbe0590SSundeep Panicker *node = g_raw->hdl; 159*6bbe0590SSundeep Panicker 160*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 161*6bbe0590SSundeep Panicker } 162*6bbe0590SSundeep Panicker 163*6bbe0590SSundeep Panicker /* ARGSUSED */ 164*6bbe0590SSundeep Panicker static fru_errno_t 165*6bbe0590SSundeep Panicker frt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer) 166*6bbe0590SSundeep Panicker { 167*6bbe0590SSundeep Panicker return (FRU_NODENOTFOUND); 168*6bbe0590SSundeep Panicker } 169*6bbe0590SSundeep Panicker /* ARGSUSED */ 170*6bbe0590SSundeep Panicker static fru_errno_t 171*6bbe0590SSundeep Panicker frt_get_child(fru_treehdl_t handle, fru_treehdl_t *child) 172*6bbe0590SSundeep Panicker { 173*6bbe0590SSundeep Panicker return (FRU_NODENOTFOUND); 174*6bbe0590SSundeep Panicker } 175*6bbe0590SSundeep Panicker 176*6bbe0590SSundeep Panicker /* ARGSUSED */ 177*6bbe0590SSundeep Panicker static fru_errno_t 178*6bbe0590SSundeep Panicker frt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent) 179*6bbe0590SSundeep Panicker { 180*6bbe0590SSundeep Panicker return (FRU_NODENOTFOUND); 181*6bbe0590SSundeep Panicker } 182*6bbe0590SSundeep Panicker 183*6bbe0590SSundeep Panicker /* ARGSUSED */ 184*6bbe0590SSundeep Panicker static fru_errno_t 185*6bbe0590SSundeep Panicker frt_get_name_from_hdl(fru_treehdl_t handle, char **name) 186*6bbe0590SSundeep Panicker { 187*6bbe0590SSundeep Panicker *name = strdup("unknown"); 188*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 189*6bbe0590SSundeep Panicker } 190*6bbe0590SSundeep Panicker 191*6bbe0590SSundeep Panicker /* ARGSUSED */ 192*6bbe0590SSundeep Panicker static fru_errno_t 193*6bbe0590SSundeep Panicker frt_get_node_type(fru_treehdl_t node, fru_node_t *type) 194*6bbe0590SSundeep Panicker { 195*6bbe0590SSundeep Panicker *type = FRU_NODE_CONTAINER; 196*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 197*6bbe0590SSundeep Panicker } 198*6bbe0590SSundeep Panicker 199*6bbe0590SSundeep Panicker 200*6bbe0590SSundeep Panicker 201*6bbe0590SSundeep Panicker static fru_errno_t 202*6bbe0590SSundeep Panicker add_segs_for_section(section_t *section, fru_strlist_t *list) 203*6bbe0590SSundeep Panicker { 204*6bbe0590SSundeep Panicker int i = 0; 205*6bbe0590SSundeep Panicker segment_t *segs = NULL; 206*6bbe0590SSundeep Panicker int acc_err = 0; 207*6bbe0590SSundeep Panicker 208*6bbe0590SSundeep Panicker int num_segment = fru_get_num_segments(section->handle, NULL); 209*6bbe0590SSundeep Panicker if (num_segment == -1) { 210*6bbe0590SSundeep Panicker return (map_errno(errno)); 211*6bbe0590SSundeep Panicker } else if (num_segment == 0) { 212*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 213*6bbe0590SSundeep Panicker } 214*6bbe0590SSundeep Panicker 215*6bbe0590SSundeep Panicker segs = malloc(sizeof (*segs) * (num_segment)); 216*6bbe0590SSundeep Panicker if (segs == NULL) { 217*6bbe0590SSundeep Panicker return (FRU_FAILURE); 218*6bbe0590SSundeep Panicker } 219*6bbe0590SSundeep Panicker 220*6bbe0590SSundeep Panicker acc_err = fru_get_segments(section->handle, segs, num_segment, NULL); 221*6bbe0590SSundeep Panicker if (acc_err == -1) { 222*6bbe0590SSundeep Panicker free(segs); 223*6bbe0590SSundeep Panicker return (map_errno(errno)); 224*6bbe0590SSundeep Panicker } 225*6bbe0590SSundeep Panicker 226*6bbe0590SSundeep Panicker list->strs = realloc(list->strs, sizeof (char *) 227*6bbe0590SSundeep Panicker * (list->num + num_segment)); 228*6bbe0590SSundeep Panicker 229*6bbe0590SSundeep Panicker for (i = 0; i < num_segment; i++) { 230*6bbe0590SSundeep Panicker /* ensure NULL terminated. */ 231*6bbe0590SSundeep Panicker char *tmp = malloc(sizeof (*tmp) * (sizeof (segs[i].name)+1)); 232*6bbe0590SSundeep Panicker if (tmp == NULL) { 233*6bbe0590SSundeep Panicker free(segs); 234*6bbe0590SSundeep Panicker return (FRU_FAILURE); 235*6bbe0590SSundeep Panicker } 236*6bbe0590SSundeep Panicker (void) memcpy(tmp, segs[i].name, sizeof (segs[i].name)); 237*6bbe0590SSundeep Panicker tmp[sizeof (segs[i].name)] = '\0'; 238*6bbe0590SSundeep Panicker 239*6bbe0590SSundeep Panicker list->strs[(list->num)++] = tmp; 240*6bbe0590SSundeep Panicker } 241*6bbe0590SSundeep Panicker 242*6bbe0590SSundeep Panicker free(segs); 243*6bbe0590SSundeep Panicker 244*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 245*6bbe0590SSundeep Panicker } 246*6bbe0590SSundeep Panicker 247*6bbe0590SSundeep Panicker 248*6bbe0590SSundeep Panicker 249*6bbe0590SSundeep Panicker static fru_errno_t 250*6bbe0590SSundeep Panicker frt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list) 251*6bbe0590SSundeep Panicker { 252*6bbe0590SSundeep Panicker fru_strlist_t rc_list; 253*6bbe0590SSundeep Panicker fru_errno_t err = FRU_SUCCESS; 254*6bbe0590SSundeep Panicker int acc_err = 0; 255*6bbe0590SSundeep Panicker int i = 0; 256*6bbe0590SSundeep Panicker int num_section = 0; 257*6bbe0590SSundeep Panicker section_t *sects = NULL; 258*6bbe0590SSundeep Panicker container_hdl_t cont; 259*6bbe0590SSundeep Panicker 260*6bbe0590SSundeep Panicker cont = treehdl_to_conthdl(handle); 261*6bbe0590SSundeep Panicker 262*6bbe0590SSundeep Panicker num_section = fru_get_num_sections(cont, NULL); 263*6bbe0590SSundeep Panicker if (num_section == -1) { 264*6bbe0590SSundeep Panicker return (map_errno(errno)); 265*6bbe0590SSundeep Panicker } 266*6bbe0590SSundeep Panicker 267*6bbe0590SSundeep Panicker sects = malloc(sizeof (*sects) * (num_section)); 268*6bbe0590SSundeep Panicker if (sects == NULL) { 269*6bbe0590SSundeep Panicker return (FRU_FAILURE); 270*6bbe0590SSundeep Panicker } 271*6bbe0590SSundeep Panicker 272*6bbe0590SSundeep Panicker acc_err = fru_get_sections(cont, sects, num_section, NULL); 273*6bbe0590SSundeep Panicker if (acc_err == -1) { 274*6bbe0590SSundeep Panicker free(sects); 275*6bbe0590SSundeep Panicker return (map_errno(errno)); 276*6bbe0590SSundeep Panicker } 277*6bbe0590SSundeep Panicker 278*6bbe0590SSundeep Panicker rc_list.num = 0; 279*6bbe0590SSundeep Panicker rc_list.strs = NULL; 280*6bbe0590SSundeep Panicker for (i = 0; i < num_section; i++) { 281*6bbe0590SSundeep Panicker if ((err = add_segs_for_section(&(sects[i]), &rc_list)) 282*6bbe0590SSundeep Panicker != FRU_SUCCESS) { 283*6bbe0590SSundeep Panicker fru_destroy_strlist(&rc_list); 284*6bbe0590SSundeep Panicker free(sects); 285*6bbe0590SSundeep Panicker return (err); 286*6bbe0590SSundeep Panicker } 287*6bbe0590SSundeep Panicker } 288*6bbe0590SSundeep Panicker 289*6bbe0590SSundeep Panicker list->strs = rc_list.strs; 290*6bbe0590SSundeep Panicker list->num = rc_list.num; 291*6bbe0590SSundeep Panicker 292*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 293*6bbe0590SSundeep Panicker } 294*6bbe0590SSundeep Panicker 295*6bbe0590SSundeep Panicker 296*6bbe0590SSundeep Panicker static fru_errno_t 297*6bbe0590SSundeep Panicker find_seg_in_sect(section_t *sect, const char *seg_name, int *prot_flg, 298*6bbe0590SSundeep Panicker segment_t *segment) 299*6bbe0590SSundeep Panicker { 300*6bbe0590SSundeep Panicker int j = 0; 301*6bbe0590SSundeep Panicker int acc_err = 0; 302*6bbe0590SSundeep Panicker segment_t *segs = NULL; 303*6bbe0590SSundeep Panicker 304*6bbe0590SSundeep Panicker int num_seg = fru_get_num_segments(sect->handle, NULL); 305*6bbe0590SSundeep Panicker if (num_seg == -1) { 306*6bbe0590SSundeep Panicker return (FRU_FAILURE); 307*6bbe0590SSundeep Panicker } 308*6bbe0590SSundeep Panicker 309*6bbe0590SSundeep Panicker segs = malloc(sizeof (*segs) * (num_seg)); 310*6bbe0590SSundeep Panicker if (segs == NULL) { 311*6bbe0590SSundeep Panicker return (FRU_FAILURE); 312*6bbe0590SSundeep Panicker } 313*6bbe0590SSundeep Panicker 314*6bbe0590SSundeep Panicker acc_err = fru_get_segments(sect->handle, segs, num_seg, NULL); 315*6bbe0590SSundeep Panicker if (acc_err == -1) { 316*6bbe0590SSundeep Panicker free(segs); 317*6bbe0590SSundeep Panicker return (map_errno(errno)); 318*6bbe0590SSundeep Panicker } 319*6bbe0590SSundeep Panicker 320*6bbe0590SSundeep Panicker for (j = 0; j < num_seg; j++) { 321*6bbe0590SSundeep Panicker /* NULL terminate */ 322*6bbe0590SSundeep Panicker char tmp[SEG_NAME_LEN+1]; 323*6bbe0590SSundeep Panicker (void) memcpy(tmp, segs[j].name, SEG_NAME_LEN); 324*6bbe0590SSundeep Panicker tmp[SEG_NAME_LEN] = '\0'; 325*6bbe0590SSundeep Panicker if (strcmp(tmp, seg_name) == 0) { 326*6bbe0590SSundeep Panicker *segment = segs[j]; 327*6bbe0590SSundeep Panicker *prot_flg = (sect->protection ? 1 : 0); 328*6bbe0590SSundeep Panicker free(segs); 329*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 330*6bbe0590SSundeep Panicker } 331*6bbe0590SSundeep Panicker } 332*6bbe0590SSundeep Panicker 333*6bbe0590SSundeep Panicker free(segs); 334*6bbe0590SSundeep Panicker return (FRU_INVALSEG); 335*6bbe0590SSundeep Panicker } 336*6bbe0590SSundeep Panicker 337*6bbe0590SSundeep Panicker 338*6bbe0590SSundeep Panicker static fru_errno_t 339*6bbe0590SSundeep Panicker find_segment(fru_treehdl_t handle, const char *seg_name, int *prot_flg, 340*6bbe0590SSundeep Panicker segment_t *segment) 341*6bbe0590SSundeep Panicker { 342*6bbe0590SSundeep Panicker int i = 0; 343*6bbe0590SSundeep Panicker int acc_err = 0; 344*6bbe0590SSundeep Panicker section_t *sect = NULL; 345*6bbe0590SSundeep Panicker container_hdl_t cont; 346*6bbe0590SSundeep Panicker int num_sect; 347*6bbe0590SSundeep Panicker 348*6bbe0590SSundeep Panicker cont = treehdl_to_conthdl(handle); 349*6bbe0590SSundeep Panicker 350*6bbe0590SSundeep Panicker num_sect = fru_get_num_sections(cont, NULL); 351*6bbe0590SSundeep Panicker if (num_sect == -1) { 352*6bbe0590SSundeep Panicker return (map_errno(errno)); 353*6bbe0590SSundeep Panicker } 354*6bbe0590SSundeep Panicker 355*6bbe0590SSundeep Panicker sect = malloc(sizeof (*sect) * (num_sect)); 356*6bbe0590SSundeep Panicker if (sect == NULL) { 357*6bbe0590SSundeep Panicker return (FRU_FAILURE); 358*6bbe0590SSundeep Panicker } 359*6bbe0590SSundeep Panicker 360*6bbe0590SSundeep Panicker acc_err = fru_get_sections(cont, sect, num_sect, NULL); 361*6bbe0590SSundeep Panicker if (acc_err == -1) { 362*6bbe0590SSundeep Panicker free(sect); 363*6bbe0590SSundeep Panicker return (map_errno(errno)); 364*6bbe0590SSundeep Panicker } 365*6bbe0590SSundeep Panicker 366*6bbe0590SSundeep Panicker for (i = 0; i < num_sect; i++) { 367*6bbe0590SSundeep Panicker if (find_seg_in_sect(&(sect[i]), seg_name, prot_flg, segment) 368*6bbe0590SSundeep Panicker == FRU_SUCCESS) { 369*6bbe0590SSundeep Panicker free(sect); 370*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 371*6bbe0590SSundeep Panicker } 372*6bbe0590SSundeep Panicker } 373*6bbe0590SSundeep Panicker 374*6bbe0590SSundeep Panicker free(sect); 375*6bbe0590SSundeep Panicker return (FRU_INVALSEG); 376*6bbe0590SSundeep Panicker } 377*6bbe0590SSundeep Panicker 378*6bbe0590SSundeep Panicker 379*6bbe0590SSundeep Panicker static fru_errno_t 380*6bbe0590SSundeep Panicker frt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def) 381*6bbe0590SSundeep Panicker { 382*6bbe0590SSundeep Panicker fru_errno_t err = FRU_SUCCESS; 383*6bbe0590SSundeep Panicker int prot_flg = 0; 384*6bbe0590SSundeep Panicker segment_t segment; 385*6bbe0590SSundeep Panicker 386*6bbe0590SSundeep Panicker if ((err = find_segment(handle, seg_name, &prot_flg, &segment)) 387*6bbe0590SSundeep Panicker != FRU_SUCCESS) { 388*6bbe0590SSundeep Panicker return (err); 389*6bbe0590SSundeep Panicker } 390*6bbe0590SSundeep Panicker 391*6bbe0590SSundeep Panicker (void) memcpy(def->name, segment.name, SEG_NAME_LEN); 392*6bbe0590SSundeep Panicker def->name[SEG_NAME_LEN] = '\0'; 393*6bbe0590SSundeep Panicker def->desc.raw_data = segment.descriptor; 394*6bbe0590SSundeep Panicker def->size = segment.length; 395*6bbe0590SSundeep Panicker def->address = segment.offset; 396*6bbe0590SSundeep Panicker 397*6bbe0590SSundeep Panicker if (prot_flg == 0) 398*6bbe0590SSundeep Panicker def->hw_desc.field.read_only = 0; 399*6bbe0590SSundeep Panicker else 400*6bbe0590SSundeep Panicker def->hw_desc.field.read_only = 1; 401*6bbe0590SSundeep Panicker 402*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 403*6bbe0590SSundeep Panicker 404*6bbe0590SSundeep Panicker } 405*6bbe0590SSundeep Panicker 406*6bbe0590SSundeep Panicker /* ARGSUSED */ 407*6bbe0590SSundeep Panicker static fru_errno_t 408*6bbe0590SSundeep Panicker frt_add_seg(fru_treehdl_t handle, fru_segdef_t *def) 409*6bbe0590SSundeep Panicker { 410*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 411*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 412*6bbe0590SSundeep Panicker } 413*6bbe0590SSundeep Panicker 414*6bbe0590SSundeep Panicker /* ARGSUSED */ 415*6bbe0590SSundeep Panicker static fru_errno_t 416*6bbe0590SSundeep Panicker frt_delete_seg(fru_treehdl_t handle, const char *seg_name) 417*6bbe0590SSundeep Panicker { 418*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 419*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 420*6bbe0590SSundeep Panicker } 421*6bbe0590SSundeep Panicker 422*6bbe0590SSundeep Panicker /* ARGSUSED */ 423*6bbe0590SSundeep Panicker static fru_errno_t 424*6bbe0590SSundeep Panicker frt_for_each_segment(fru_nodehdl_t node, 425*6bbe0590SSundeep Panicker int (*function)(fru_seghdl_t hdl, void *args), void *args) 426*6bbe0590SSundeep Panicker { 427*6bbe0590SSundeep Panicker int num_segment; 428*6bbe0590SSundeep Panicker int cnt; 429*6bbe0590SSundeep Panicker int num_sect; 430*6bbe0590SSundeep Panicker int each_seg; 431*6bbe0590SSundeep Panicker section_t *sects; 432*6bbe0590SSundeep Panicker segment_t *segs; 433*6bbe0590SSundeep Panicker segment_list_t *tmp_list; 434*6bbe0590SSundeep Panicker int acc_err; 435*6bbe0590SSundeep Panicker int status; 436*6bbe0590SSundeep Panicker container_hdl_t cont; 437*6bbe0590SSundeep Panicker 438*6bbe0590SSundeep Panicker cont = g_raw->cont; 439*6bbe0590SSundeep Panicker 440*6bbe0590SSundeep Panicker num_sect = fru_get_num_sections(cont, NULL); 441*6bbe0590SSundeep Panicker if (num_sect == -1) { 442*6bbe0590SSundeep Panicker return (map_errno(errno)); 443*6bbe0590SSundeep Panicker } 444*6bbe0590SSundeep Panicker 445*6bbe0590SSundeep Panicker sects = malloc((num_sect + 1) * sizeof (section_t)); 446*6bbe0590SSundeep Panicker if (sects == NULL) { 447*6bbe0590SSundeep Panicker return (FRU_FAILURE); 448*6bbe0590SSundeep Panicker } 449*6bbe0590SSundeep Panicker num_sect = fru_get_sections(cont, sects, num_sect, NULL); 450*6bbe0590SSundeep Panicker if (num_sect == -1) { 451*6bbe0590SSundeep Panicker free(sects); 452*6bbe0590SSundeep Panicker return (map_errno(errno)); 453*6bbe0590SSundeep Panicker } 454*6bbe0590SSundeep Panicker for (cnt = 0; cnt < num_sect; cnt++) { 455*6bbe0590SSundeep Panicker num_segment = fru_get_num_segments(sects[cnt].handle, NULL); 456*6bbe0590SSundeep Panicker if (num_segment == -1) { 457*6bbe0590SSundeep Panicker return (map_errno(errno)); 458*6bbe0590SSundeep Panicker } else if (num_segment == 0) { 459*6bbe0590SSundeep Panicker continue; 460*6bbe0590SSundeep Panicker } 461*6bbe0590SSundeep Panicker segs = malloc((num_segment + 1) * sizeof (segment_t)); 462*6bbe0590SSundeep Panicker if (segs == NULL) { 463*6bbe0590SSundeep Panicker free(sects); 464*6bbe0590SSundeep Panicker return (FRU_FAILURE); 465*6bbe0590SSundeep Panicker } 466*6bbe0590SSundeep Panicker acc_err = fru_get_segments(sects[cnt].handle, segs, 467*6bbe0590SSundeep Panicker num_segment, NULL); 468*6bbe0590SSundeep Panicker if (acc_err == -1) { 469*6bbe0590SSundeep Panicker free(sects); 470*6bbe0590SSundeep Panicker free(segs); 471*6bbe0590SSundeep Panicker return (map_errno(errno)); 472*6bbe0590SSundeep Panicker } 473*6bbe0590SSundeep Panicker for (each_seg = 0; each_seg < num_segment; each_seg++) { 474*6bbe0590SSundeep Panicker tmp_list = malloc(sizeof (segment_list_t)); 475*6bbe0590SSundeep Panicker tmp_list->segment = &segs[each_seg]; 476*6bbe0590SSundeep Panicker tmp_list->next = NULL; 477*6bbe0590SSundeep Panicker if (g_raw->segs == NULL) { 478*6bbe0590SSundeep Panicker g_raw->segs = tmp_list; 479*6bbe0590SSundeep Panicker } else { 480*6bbe0590SSundeep Panicker tmp_list->next = g_raw->segs; 481*6bbe0590SSundeep Panicker g_raw->segs = tmp_list; 482*6bbe0590SSundeep Panicker } 483*6bbe0590SSundeep Panicker 484*6bbe0590SSundeep Panicker if ((status = function(segs[each_seg].handle, args)) 485*6bbe0590SSundeep Panicker != FRU_SUCCESS) { 486*6bbe0590SSundeep Panicker free(segs); 487*6bbe0590SSundeep Panicker free(sects); 488*6bbe0590SSundeep Panicker return (status); 489*6bbe0590SSundeep Panicker } 490*6bbe0590SSundeep Panicker } 491*6bbe0590SSundeep Panicker free(segs); 492*6bbe0590SSundeep Panicker free(sects); 493*6bbe0590SSundeep Panicker 494*6bbe0590SSundeep Panicker } 495*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 496*6bbe0590SSundeep Panicker } 497*6bbe0590SSundeep Panicker 498*6bbe0590SSundeep Panicker 499*6bbe0590SSundeep Panicker static fru_errno_t 500*6bbe0590SSundeep Panicker frt_get_segment_name(fru_seghdl_t node, char **name) 501*6bbe0590SSundeep Panicker { 502*6bbe0590SSundeep Panicker int num_sect; 503*6bbe0590SSundeep Panicker int acc_err; 504*6bbe0590SSundeep Panicker int cnt; 505*6bbe0590SSundeep Panicker int num_segment; 506*6bbe0590SSundeep Panicker section_t *sects; 507*6bbe0590SSundeep Panicker segment_t *segs; 508*6bbe0590SSundeep Panicker int each_seg; 509*6bbe0590SSundeep Panicker container_hdl_t cont; 510*6bbe0590SSundeep Panicker 511*6bbe0590SSundeep Panicker cont = treehdl_to_conthdl(node); 512*6bbe0590SSundeep Panicker 513*6bbe0590SSundeep Panicker num_sect = fru_get_num_sections(cont, NULL); 514*6bbe0590SSundeep Panicker if (num_sect == -1) { 515*6bbe0590SSundeep Panicker return (map_errno(errno)); 516*6bbe0590SSundeep Panicker } 517*6bbe0590SSundeep Panicker 518*6bbe0590SSundeep Panicker sects = malloc(sizeof (*sects) * (num_sect)); 519*6bbe0590SSundeep Panicker if (sects == NULL) { 520*6bbe0590SSundeep Panicker return (FRU_FAILURE); 521*6bbe0590SSundeep Panicker } 522*6bbe0590SSundeep Panicker acc_err = fru_get_sections(cont, sects, num_sect, NULL); 523*6bbe0590SSundeep Panicker if (acc_err == -1) { 524*6bbe0590SSundeep Panicker free(sects); 525*6bbe0590SSundeep Panicker return (map_errno(errno)); 526*6bbe0590SSundeep Panicker } 527*6bbe0590SSundeep Panicker 528*6bbe0590SSundeep Panicker for (cnt = 0; cnt < num_sect; cnt++) { 529*6bbe0590SSundeep Panicker num_segment = fru_get_num_segments(sects[cnt].handle, NULL); 530*6bbe0590SSundeep Panicker if (num_segment == -1) { 531*6bbe0590SSundeep Panicker free(sects); 532*6bbe0590SSundeep Panicker return (map_errno(errno)); 533*6bbe0590SSundeep Panicker } else if (num_segment == 0) { 534*6bbe0590SSundeep Panicker continue; 535*6bbe0590SSundeep Panicker } 536*6bbe0590SSundeep Panicker 537*6bbe0590SSundeep Panicker segs = malloc(sizeof (*segs) * (num_segment)); 538*6bbe0590SSundeep Panicker if (segs == NULL) { 539*6bbe0590SSundeep Panicker free(sects); 540*6bbe0590SSundeep Panicker return (FRU_FAILURE); 541*6bbe0590SSundeep Panicker } 542*6bbe0590SSundeep Panicker 543*6bbe0590SSundeep Panicker acc_err = fru_get_segments(sects[cnt].handle, segs, 544*6bbe0590SSundeep Panicker num_segment, NULL); 545*6bbe0590SSundeep Panicker if (acc_err == -1) { 546*6bbe0590SSundeep Panicker free(sects); 547*6bbe0590SSundeep Panicker free(segs); 548*6bbe0590SSundeep Panicker return (map_errno(errno)); 549*6bbe0590SSundeep Panicker } 550*6bbe0590SSundeep Panicker 551*6bbe0590SSundeep Panicker for (each_seg = 0; each_seg < num_segment; each_seg++) { 552*6bbe0590SSundeep Panicker if (segs[each_seg].handle == node) { 553*6bbe0590SSundeep Panicker segs[each_seg].name[FRU_SEGNAMELEN] = '\0'; 554*6bbe0590SSundeep Panicker *name = segs[each_seg].name; 555*6bbe0590SSundeep Panicker free(sects); 556*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 557*6bbe0590SSundeep Panicker } 558*6bbe0590SSundeep Panicker } 559*6bbe0590SSundeep Panicker free(segs); 560*6bbe0590SSundeep Panicker } 561*6bbe0590SSundeep Panicker 562*6bbe0590SSundeep Panicker return (FRU_FAILURE); 563*6bbe0590SSundeep Panicker } 564*6bbe0590SSundeep Panicker 565*6bbe0590SSundeep Panicker 566*6bbe0590SSundeep Panicker /* ARGSUSED */ 567*6bbe0590SSundeep Panicker static fru_errno_t 568*6bbe0590SSundeep Panicker frt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name, 569*6bbe0590SSundeep Panicker fru_tag_t tag, uint8_t *data, size_t data_len) 570*6bbe0590SSundeep Panicker { 571*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 572*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 573*6bbe0590SSundeep Panicker } 574*6bbe0590SSundeep Panicker 575*6bbe0590SSundeep Panicker 576*6bbe0590SSundeep Panicker /* ARGSUSED */ 577*6bbe0590SSundeep Panicker static fru_errno_t 578*6bbe0590SSundeep Panicker frt_get_tag_list(fru_treehdl_t handle, const char *seg_name, 579*6bbe0590SSundeep Panicker fru_tag_t **tags, int *number) 580*6bbe0590SSundeep Panicker { 581*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 582*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 583*6bbe0590SSundeep Panicker } 584*6bbe0590SSundeep Panicker 585*6bbe0590SSundeep Panicker 586*6bbe0590SSundeep Panicker /* ARGSUSED */ 587*6bbe0590SSundeep Panicker static fru_errno_t 588*6bbe0590SSundeep Panicker frt_get_tag_data(fru_treehdl_t handle, const char *seg_name, 589*6bbe0590SSundeep Panicker fru_tag_t tag, int instance, 590*6bbe0590SSundeep Panicker uint8_t **data, size_t *data_len) 591*6bbe0590SSundeep Panicker { 592*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 593*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 594*6bbe0590SSundeep Panicker } 595*6bbe0590SSundeep Panicker 596*6bbe0590SSundeep Panicker 597*6bbe0590SSundeep Panicker /* ARGSUSED */ 598*6bbe0590SSundeep Panicker static fru_errno_t 599*6bbe0590SSundeep Panicker frt_set_tag_data(fru_treehdl_t handle, const char *seg_name, 600*6bbe0590SSundeep Panicker fru_tag_t tag, int instance, 601*6bbe0590SSundeep Panicker uint8_t *data, size_t data_len) 602*6bbe0590SSundeep Panicker { 603*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 604*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 605*6bbe0590SSundeep Panicker } 606*6bbe0590SSundeep Panicker 607*6bbe0590SSundeep Panicker 608*6bbe0590SSundeep Panicker /* ARGSUSED */ 609*6bbe0590SSundeep Panicker static fru_errno_t 610*6bbe0590SSundeep Panicker frt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag, 611*6bbe0590SSundeep Panicker int instance) 612*6bbe0590SSundeep Panicker { 613*6bbe0590SSundeep Panicker /* NOT SUPPORTED */ 614*6bbe0590SSundeep Panicker return (FRU_NOTSUP); 615*6bbe0590SSundeep Panicker } 616*6bbe0590SSundeep Panicker 617*6bbe0590SSundeep Panicker 618*6bbe0590SSundeep Panicker static fru_errno_t 619*6bbe0590SSundeep Panicker frt_for_each_packet(fru_seghdl_t node, 620*6bbe0590SSundeep Panicker int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length, 621*6bbe0590SSundeep Panicker void *args), void *args) 622*6bbe0590SSundeep Panicker { 623*6bbe0590SSundeep Panicker int rc_num; 624*6bbe0590SSundeep Panicker int status; 625*6bbe0590SSundeep Panicker char *rc_tags; 626*6bbe0590SSundeep Panicker char *rc_data; 627*6bbe0590SSundeep Panicker int i; 628*6bbe0590SSundeep Panicker packet_t *packets = NULL; 629*6bbe0590SSundeep Panicker segment_list_t *tmp_list; 630*6bbe0590SSundeep Panicker fru_segdesc_t *descriptor; 631*6bbe0590SSundeep Panicker 632*6bbe0590SSundeep Panicker tmp_list = g_raw->segs; 633*6bbe0590SSundeep Panicker 634*6bbe0590SSundeep Panicker /* num of packet */ 635*6bbe0590SSundeep Panicker rc_num = fru_get_num_packets(node, NULL); 636*6bbe0590SSundeep Panicker if (rc_num == -1) { 637*6bbe0590SSundeep Panicker return (map_errno(errno)); 638*6bbe0590SSundeep Panicker } else if (rc_num == 0) { 639*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 640*6bbe0590SSundeep Panicker } 641*6bbe0590SSundeep Panicker while (tmp_list) { 642*6bbe0590SSundeep Panicker if (node == tmp_list->segment->handle) { 643*6bbe0590SSundeep Panicker break; 644*6bbe0590SSundeep Panicker } 645*6bbe0590SSundeep Panicker tmp_list = tmp_list->next; 646*6bbe0590SSundeep Panicker } 647*6bbe0590SSundeep Panicker if (tmp_list) { 648*6bbe0590SSundeep Panicker descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor; 649*6bbe0590SSundeep Panicker if (descriptor->field.opaque) { 650*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 651*6bbe0590SSundeep Panicker } 652*6bbe0590SSundeep Panicker 653*6bbe0590SSundeep Panicker if (descriptor->field.encrypted && (encrypt_func == NULL)) { 654*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 655*6bbe0590SSundeep Panicker } 656*6bbe0590SSundeep Panicker } 657*6bbe0590SSundeep Panicker 658*6bbe0590SSundeep Panicker packets = malloc(sizeof (*packets) * (rc_num)); 659*6bbe0590SSundeep Panicker if (packets == NULL) { 660*6bbe0590SSundeep Panicker return (FRU_FAILURE); 661*6bbe0590SSundeep Panicker } 662*6bbe0590SSundeep Panicker /* get all packets */ 663*6bbe0590SSundeep Panicker if (fru_get_packets(node, packets, rc_num, NULL) == -1) { 664*6bbe0590SSundeep Panicker free(packets); 665*6bbe0590SSundeep Panicker return (map_errno(errno)); 666*6bbe0590SSundeep Panicker } 667*6bbe0590SSundeep Panicker 668*6bbe0590SSundeep Panicker rc_tags = malloc(sizeof (*rc_tags) * (rc_num)); 669*6bbe0590SSundeep Panicker if (rc_tags == NULL) { 670*6bbe0590SSundeep Panicker free(packets); 671*6bbe0590SSundeep Panicker return (FRU_FAILURE); 672*6bbe0590SSundeep Panicker } 673*6bbe0590SSundeep Panicker 674*6bbe0590SSundeep Panicker /* number of tags */ 675*6bbe0590SSundeep Panicker for (i = 0; i < rc_num; i++) { 676*6bbe0590SSundeep Panicker size_t rc_len = 677*6bbe0590SSundeep Panicker get_payload_length((fru_tag_t *)&packets[i].tag); 678*6bbe0590SSundeep Panicker 679*6bbe0590SSundeep Panicker rc_data = malloc(sizeof (*rc_data) * (rc_len)); 680*6bbe0590SSundeep Panicker if (rc_data == NULL) { 681*6bbe0590SSundeep Panicker free(packets); 682*6bbe0590SSundeep Panicker return (FRU_FAILURE); 683*6bbe0590SSundeep Panicker } 684*6bbe0590SSundeep Panicker /* get the payload data */ 685*6bbe0590SSundeep Panicker (void) fru_get_payload(packets[i].handle, (void *)rc_data, 686*6bbe0590SSundeep Panicker rc_len, NULL); 687*6bbe0590SSundeep Panicker 688*6bbe0590SSundeep Panicker if (tmp_list) { 689*6bbe0590SSundeep Panicker descriptor = 690*6bbe0590SSundeep Panicker (fru_segdesc_t *)&tmp_list->segment->descriptor; 691*6bbe0590SSundeep Panicker 692*6bbe0590SSundeep Panicker if ((descriptor->field.encrypted) && 693*6bbe0590SSundeep Panicker ((status = encrypt_func(FRU_DECRYPT, 694*6bbe0590SSundeep Panicker (void *)rc_data, rc_len)) 695*6bbe0590SSundeep Panicker != FRU_SUCCESS)) { 696*6bbe0590SSundeep Panicker return (status); 697*6bbe0590SSundeep Panicker } 698*6bbe0590SSundeep Panicker } 699*6bbe0590SSundeep Panicker /* print packet */ 700*6bbe0590SSundeep Panicker if ((status = function((fru_tag_t *)&packets[i].tag, 701*6bbe0590SSundeep Panicker (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) { 702*6bbe0590SSundeep Panicker free(rc_data); 703*6bbe0590SSundeep Panicker free(packets); 704*6bbe0590SSundeep Panicker return (status); 705*6bbe0590SSundeep Panicker } 706*6bbe0590SSundeep Panicker free(rc_data); 707*6bbe0590SSundeep Panicker } 708*6bbe0590SSundeep Panicker return (FRU_SUCCESS); 709*6bbe0590SSundeep Panicker 710*6bbe0590SSundeep Panicker } 711*6bbe0590SSundeep Panicker 712*6bbe0590SSundeep Panicker 713*6bbe0590SSundeep Panicker /* object for libfru to link to */ 714*6bbe0590SSundeep Panicker fru_datasource_t data_source = 715*6bbe0590SSundeep Panicker { 716*6bbe0590SSundeep Panicker LIBFRU_DS_VER, 717*6bbe0590SSundeep Panicker frt_initialize, 718*6bbe0590SSundeep Panicker frt_shutdown, 719*6bbe0590SSundeep Panicker frt_get_root, 720*6bbe0590SSundeep Panicker frt_get_child, 721*6bbe0590SSundeep Panicker frt_get_peer, 722*6bbe0590SSundeep Panicker frt_get_parent, 723*6bbe0590SSundeep Panicker frt_get_name_from_hdl, 724*6bbe0590SSundeep Panicker frt_get_node_type, 725*6bbe0590SSundeep Panicker frt_get_seg_list, 726*6bbe0590SSundeep Panicker frt_get_seg_def, 727*6bbe0590SSundeep Panicker frt_add_seg, 728*6bbe0590SSundeep Panicker frt_delete_seg, 729*6bbe0590SSundeep Panicker frt_for_each_segment, 730*6bbe0590SSundeep Panicker frt_get_segment_name, 731*6bbe0590SSundeep Panicker frt_add_tag_to_seg, 732*6bbe0590SSundeep Panicker frt_get_tag_list, 733*6bbe0590SSundeep Panicker frt_get_tag_data, 734*6bbe0590SSundeep Panicker frt_set_tag_data, 735*6bbe0590SSundeep Panicker frt_delete_tag, 736*6bbe0590SSundeep Panicker frt_for_each_packet 737*6bbe0590SSundeep Panicker }; 738