16bbe0590SSundeep Panicker /* 26bbe0590SSundeep Panicker * CDDL HEADER START 36bbe0590SSundeep Panicker * 46bbe0590SSundeep Panicker * The contents of this file are subject to the terms of the 56bbe0590SSundeep Panicker * Common Development and Distribution License (the "License"). 66bbe0590SSundeep Panicker * You may not use this file except in compliance with the License. 76bbe0590SSundeep Panicker * 86bbe0590SSundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96bbe0590SSundeep Panicker * or http://www.opensolaris.org/os/licensing. 106bbe0590SSundeep Panicker * See the License for the specific language governing permissions 116bbe0590SSundeep Panicker * and limitations under the License. 126bbe0590SSundeep Panicker * 136bbe0590SSundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each 146bbe0590SSundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156bbe0590SSundeep Panicker * If applicable, add the following below this CDDL HEADER, with the 166bbe0590SSundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying 176bbe0590SSundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner] 186bbe0590SSundeep Panicker * 196bbe0590SSundeep Panicker * CDDL HEADER END 206bbe0590SSundeep Panicker */ 216bbe0590SSundeep Panicker 226bbe0590SSundeep Panicker /* 23*ac88567aSHyon Kim * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 246bbe0590SSundeep Panicker */ 256bbe0590SSundeep Panicker 266bbe0590SSundeep Panicker #include <stdio.h> 276bbe0590SSundeep Panicker #include <stdarg.h> 286bbe0590SSundeep Panicker #include <stdlib.h> 296bbe0590SSundeep Panicker #include <errno.h> 306bbe0590SSundeep Panicker #include <string.h> 316bbe0590SSundeep Panicker 326bbe0590SSundeep Panicker #include "fru_access_impl.h" 336bbe0590SSundeep Panicker 346bbe0590SSundeep Panicker #include "libfruds.h" 356bbe0590SSundeep Panicker #include "libfrup.h" 366bbe0590SSundeep Panicker #include "fru_access.h" 376bbe0590SSundeep Panicker #include "fruraw.h" 386bbe0590SSundeep Panicker 396bbe0590SSundeep Panicker 406bbe0590SSundeep Panicker raw_list_t *g_raw = NULL; 416bbe0590SSundeep Panicker 426bbe0590SSundeep Panicker 436bbe0590SSundeep Panicker /* ARGSUSED */ 446bbe0590SSundeep Panicker static raw_list_t * 456bbe0590SSundeep Panicker treehdl_to_rawlist(fru_treehdl_t handle) 466bbe0590SSundeep Panicker { 476bbe0590SSundeep Panicker return (g_raw); 486bbe0590SSundeep Panicker } 496bbe0590SSundeep Panicker 506bbe0590SSundeep Panicker 516bbe0590SSundeep Panicker static container_hdl_t 526bbe0590SSundeep Panicker treehdl_to_conthdl(fru_treehdl_t handle) 536bbe0590SSundeep Panicker { 546bbe0590SSundeep Panicker raw_list_t *ptr; 556bbe0590SSundeep Panicker 566bbe0590SSundeep Panicker ptr = treehdl_to_rawlist(handle); 576bbe0590SSundeep Panicker if (ptr == NULL) { 586bbe0590SSundeep Panicker return (-1); 596bbe0590SSundeep Panicker } 606bbe0590SSundeep Panicker 616bbe0590SSundeep Panicker return (ptr->cont); 626bbe0590SSundeep Panicker } 636bbe0590SSundeep Panicker 646bbe0590SSundeep Panicker 656bbe0590SSundeep Panicker static fru_errno_t 666bbe0590SSundeep Panicker map_errno(int err) 676bbe0590SSundeep Panicker { 686bbe0590SSundeep Panicker switch (err) { 696bbe0590SSundeep Panicker case ENFILE: 706bbe0590SSundeep Panicker case EEXIST: 716bbe0590SSundeep Panicker return (FRU_DUPSEG); 726bbe0590SSundeep Panicker case EAGAIN: 736bbe0590SSundeep Panicker return (FRU_NOSPACE); 746bbe0590SSundeep Panicker case EPERM: 756bbe0590SSundeep Panicker return (FRU_INVALPERM); 766bbe0590SSundeep Panicker default : 776bbe0590SSundeep Panicker return (FRU_IOERROR); 786bbe0590SSundeep Panicker } 796bbe0590SSundeep Panicker } 806bbe0590SSundeep Panicker 816bbe0590SSundeep Panicker 826bbe0590SSundeep Panicker static raw_list_t * 836bbe0590SSundeep Panicker make_raw(uint8_t *buffer, size_t size, char *cont_type) 846bbe0590SSundeep Panicker { 856bbe0590SSundeep Panicker raw_list_t *node; 866bbe0590SSundeep Panicker 876bbe0590SSundeep Panicker node = (raw_list_t *)malloc(sizeof (raw_list_t)); 886bbe0590SSundeep Panicker if (node == NULL) { 896bbe0590SSundeep Panicker return (NULL); 906bbe0590SSundeep Panicker } 916bbe0590SSundeep Panicker 926bbe0590SSundeep Panicker node->hdl = 0; 936bbe0590SSundeep Panicker node->raw = buffer; 946bbe0590SSundeep Panicker node->size = size; 956bbe0590SSundeep Panicker node->cont_type = strdup(cont_type); 966bbe0590SSundeep Panicker if (node->cont_type == NULL) { 976bbe0590SSundeep Panicker free(node); 986bbe0590SSundeep Panicker return (NULL); 996bbe0590SSundeep Panicker } 1006bbe0590SSundeep Panicker node->segs = NULL; 1016bbe0590SSundeep Panicker 1026bbe0590SSundeep Panicker return (node); 1036bbe0590SSundeep Panicker } 1046bbe0590SSundeep Panicker 1056bbe0590SSundeep Panicker 1066bbe0590SSundeep Panicker /* 1076bbe0590SSundeep Panicker * Arguments : 1086bbe0590SSundeep Panicker * 0 - pointer to byte buffer (in) 1096bbe0590SSundeep Panicker * 1 - size of buffer (in) 1106bbe0590SSundeep Panicker * 2 - container type, string (in) 1116bbe0590SSundeep Panicker */ 1126bbe0590SSundeep Panicker static fru_errno_t 1136bbe0590SSundeep Panicker frt_initialize(int num, char **args) 1146bbe0590SSundeep Panicker { 1156bbe0590SSundeep Panicker 1166bbe0590SSundeep Panicker 1176bbe0590SSundeep Panicker if (num != 3) { 1186bbe0590SSundeep Panicker return (FRU_FAILURE); 1196bbe0590SSundeep Panicker } 1206bbe0590SSundeep Panicker 1216bbe0590SSundeep Panicker g_raw = make_raw((uint8_t *)args[0], (size_t)args[1], args[2]); 1226bbe0590SSundeep Panicker if (g_raw == NULL) { 1236bbe0590SSundeep Panicker return (FRU_FAILURE); 1246bbe0590SSundeep Panicker } 1256bbe0590SSundeep Panicker 1266bbe0590SSundeep Panicker g_raw->cont = open_raw_data(g_raw); 1276bbe0590SSundeep Panicker if (g_raw->cont == NULL) { 1286bbe0590SSundeep Panicker return (FRU_FAILURE); 1296bbe0590SSundeep Panicker } 1306bbe0590SSundeep Panicker 1316bbe0590SSundeep Panicker return (FRU_SUCCESS); 1326bbe0590SSundeep Panicker } 1336bbe0590SSundeep Panicker 1346bbe0590SSundeep Panicker 1356bbe0590SSundeep Panicker static fru_errno_t 1366bbe0590SSundeep Panicker frt_shutdown(void) 1376bbe0590SSundeep Panicker { 1386bbe0590SSundeep Panicker segment_list_t *lptr, *lptr2; 1396bbe0590SSundeep Panicker 1406bbe0590SSundeep Panicker (void) fru_close_container(g_raw->cont); 1416bbe0590SSundeep Panicker free(g_raw->cont_type); 1426bbe0590SSundeep Panicker lptr = g_raw->segs; 1436bbe0590SSundeep Panicker while (lptr) { 1446bbe0590SSundeep Panicker lptr2 = lptr; 1456bbe0590SSundeep Panicker lptr = lptr->next; 1466bbe0590SSundeep Panicker free(lptr2); 1476bbe0590SSundeep Panicker } 1486bbe0590SSundeep Panicker g_raw = NULL; 1496bbe0590SSundeep Panicker 1506bbe0590SSundeep Panicker return (FRU_SUCCESS); 1516bbe0590SSundeep Panicker } 1526bbe0590SSundeep Panicker 1536bbe0590SSundeep Panicker 1546bbe0590SSundeep Panicker static fru_errno_t 1556bbe0590SSundeep Panicker frt_get_root(fru_treehdl_t *node) 1566bbe0590SSundeep Panicker { 1576bbe0590SSundeep Panicker *node = g_raw->hdl; 1586bbe0590SSundeep Panicker 1596bbe0590SSundeep Panicker return (FRU_SUCCESS); 1606bbe0590SSundeep Panicker } 1616bbe0590SSundeep Panicker 1626bbe0590SSundeep Panicker /* ARGSUSED */ 1636bbe0590SSundeep Panicker static fru_errno_t 1646bbe0590SSundeep Panicker frt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer) 1656bbe0590SSundeep Panicker { 1666bbe0590SSundeep Panicker return (FRU_NODENOTFOUND); 1676bbe0590SSundeep Panicker } 1686bbe0590SSundeep Panicker /* ARGSUSED */ 1696bbe0590SSundeep Panicker static fru_errno_t 1706bbe0590SSundeep Panicker frt_get_child(fru_treehdl_t handle, fru_treehdl_t *child) 1716bbe0590SSundeep Panicker { 1726bbe0590SSundeep Panicker return (FRU_NODENOTFOUND); 1736bbe0590SSundeep Panicker } 1746bbe0590SSundeep Panicker 1756bbe0590SSundeep Panicker /* ARGSUSED */ 1766bbe0590SSundeep Panicker static fru_errno_t 1776bbe0590SSundeep Panicker frt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent) 1786bbe0590SSundeep Panicker { 1796bbe0590SSundeep Panicker return (FRU_NODENOTFOUND); 1806bbe0590SSundeep Panicker } 1816bbe0590SSundeep Panicker 1826bbe0590SSundeep Panicker /* ARGSUSED */ 1836bbe0590SSundeep Panicker static fru_errno_t 1846bbe0590SSundeep Panicker frt_get_name_from_hdl(fru_treehdl_t handle, char **name) 1856bbe0590SSundeep Panicker { 1866bbe0590SSundeep Panicker *name = strdup("unknown"); 1876bbe0590SSundeep Panicker return (FRU_SUCCESS); 1886bbe0590SSundeep Panicker } 1896bbe0590SSundeep Panicker 1906bbe0590SSundeep Panicker /* ARGSUSED */ 1916bbe0590SSundeep Panicker static fru_errno_t 1926bbe0590SSundeep Panicker frt_get_node_type(fru_treehdl_t node, fru_node_t *type) 1936bbe0590SSundeep Panicker { 1946bbe0590SSundeep Panicker *type = FRU_NODE_CONTAINER; 1956bbe0590SSundeep Panicker return (FRU_SUCCESS); 1966bbe0590SSundeep Panicker } 1976bbe0590SSundeep Panicker 1986bbe0590SSundeep Panicker 1996bbe0590SSundeep Panicker 2006bbe0590SSundeep Panicker static fru_errno_t 2016bbe0590SSundeep Panicker add_segs_for_section(section_t *section, fru_strlist_t *list) 2026bbe0590SSundeep Panicker { 2036bbe0590SSundeep Panicker int i = 0; 2046bbe0590SSundeep Panicker segment_t *segs = NULL; 2056bbe0590SSundeep Panicker int acc_err = 0; 2066bbe0590SSundeep Panicker 2076bbe0590SSundeep Panicker int num_segment = fru_get_num_segments(section->handle, NULL); 2086bbe0590SSundeep Panicker if (num_segment == -1) { 2096bbe0590SSundeep Panicker return (map_errno(errno)); 2106bbe0590SSundeep Panicker } else if (num_segment == 0) { 2116bbe0590SSundeep Panicker return (FRU_SUCCESS); 2126bbe0590SSundeep Panicker } 2136bbe0590SSundeep Panicker 2146bbe0590SSundeep Panicker segs = malloc(sizeof (*segs) * (num_segment)); 2156bbe0590SSundeep Panicker if (segs == NULL) { 2166bbe0590SSundeep Panicker return (FRU_FAILURE); 2176bbe0590SSundeep Panicker } 2186bbe0590SSundeep Panicker 2196bbe0590SSundeep Panicker acc_err = fru_get_segments(section->handle, segs, num_segment, NULL); 2206bbe0590SSundeep Panicker if (acc_err == -1) { 2216bbe0590SSundeep Panicker free(segs); 2226bbe0590SSundeep Panicker return (map_errno(errno)); 2236bbe0590SSundeep Panicker } 2246bbe0590SSundeep Panicker 2256bbe0590SSundeep Panicker list->strs = realloc(list->strs, sizeof (char *) 2266bbe0590SSundeep Panicker * (list->num + num_segment)); 2276bbe0590SSundeep Panicker 2286bbe0590SSundeep Panicker for (i = 0; i < num_segment; i++) { 2296bbe0590SSundeep Panicker /* ensure NULL terminated. */ 2306bbe0590SSundeep Panicker char *tmp = malloc(sizeof (*tmp) * (sizeof (segs[i].name)+1)); 2316bbe0590SSundeep Panicker if (tmp == NULL) { 2326bbe0590SSundeep Panicker free(segs); 2336bbe0590SSundeep Panicker return (FRU_FAILURE); 2346bbe0590SSundeep Panicker } 2356bbe0590SSundeep Panicker (void) memcpy(tmp, segs[i].name, sizeof (segs[i].name)); 2366bbe0590SSundeep Panicker tmp[sizeof (segs[i].name)] = '\0'; 2376bbe0590SSundeep Panicker 2386bbe0590SSundeep Panicker list->strs[(list->num)++] = tmp; 2396bbe0590SSundeep Panicker } 2406bbe0590SSundeep Panicker 2416bbe0590SSundeep Panicker free(segs); 2426bbe0590SSundeep Panicker 2436bbe0590SSundeep Panicker return (FRU_SUCCESS); 2446bbe0590SSundeep Panicker } 2456bbe0590SSundeep Panicker 2466bbe0590SSundeep Panicker 2476bbe0590SSundeep Panicker 2486bbe0590SSundeep Panicker static fru_errno_t 2496bbe0590SSundeep Panicker frt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list) 2506bbe0590SSundeep Panicker { 2516bbe0590SSundeep Panicker fru_strlist_t rc_list; 2526bbe0590SSundeep Panicker fru_errno_t err = FRU_SUCCESS; 2536bbe0590SSundeep Panicker int acc_err = 0; 2546bbe0590SSundeep Panicker int i = 0; 2556bbe0590SSundeep Panicker int num_section = 0; 2566bbe0590SSundeep Panicker section_t *sects = NULL; 2576bbe0590SSundeep Panicker container_hdl_t cont; 2586bbe0590SSundeep Panicker 2596bbe0590SSundeep Panicker cont = treehdl_to_conthdl(handle); 2606bbe0590SSundeep Panicker 2616bbe0590SSundeep Panicker num_section = fru_get_num_sections(cont, NULL); 2626bbe0590SSundeep Panicker if (num_section == -1) { 2636bbe0590SSundeep Panicker return (map_errno(errno)); 2646bbe0590SSundeep Panicker } 2656bbe0590SSundeep Panicker 2666bbe0590SSundeep Panicker sects = malloc(sizeof (*sects) * (num_section)); 2676bbe0590SSundeep Panicker if (sects == NULL) { 2686bbe0590SSundeep Panicker return (FRU_FAILURE); 2696bbe0590SSundeep Panicker } 2706bbe0590SSundeep Panicker 2716bbe0590SSundeep Panicker acc_err = fru_get_sections(cont, sects, num_section, NULL); 2726bbe0590SSundeep Panicker if (acc_err == -1) { 2736bbe0590SSundeep Panicker free(sects); 2746bbe0590SSundeep Panicker return (map_errno(errno)); 2756bbe0590SSundeep Panicker } 2766bbe0590SSundeep Panicker 2776bbe0590SSundeep Panicker rc_list.num = 0; 2786bbe0590SSundeep Panicker rc_list.strs = NULL; 2796bbe0590SSundeep Panicker for (i = 0; i < num_section; i++) { 2806bbe0590SSundeep Panicker if ((err = add_segs_for_section(&(sects[i]), &rc_list)) 2816bbe0590SSundeep Panicker != FRU_SUCCESS) { 2826bbe0590SSundeep Panicker fru_destroy_strlist(&rc_list); 2836bbe0590SSundeep Panicker free(sects); 2846bbe0590SSundeep Panicker return (err); 2856bbe0590SSundeep Panicker } 2866bbe0590SSundeep Panicker } 2876bbe0590SSundeep Panicker 2886bbe0590SSundeep Panicker list->strs = rc_list.strs; 2896bbe0590SSundeep Panicker list->num = rc_list.num; 2906bbe0590SSundeep Panicker 2916bbe0590SSundeep Panicker return (FRU_SUCCESS); 2926bbe0590SSundeep Panicker } 2936bbe0590SSundeep Panicker 2946bbe0590SSundeep Panicker 2956bbe0590SSundeep Panicker static fru_errno_t 2966bbe0590SSundeep Panicker find_seg_in_sect(section_t *sect, const char *seg_name, int *prot_flg, 2976bbe0590SSundeep Panicker segment_t *segment) 2986bbe0590SSundeep Panicker { 2996bbe0590SSundeep Panicker int j = 0; 3006bbe0590SSundeep Panicker int acc_err = 0; 3016bbe0590SSundeep Panicker segment_t *segs = NULL; 3026bbe0590SSundeep Panicker 3036bbe0590SSundeep Panicker int num_seg = fru_get_num_segments(sect->handle, NULL); 3046bbe0590SSundeep Panicker if (num_seg == -1) { 3056bbe0590SSundeep Panicker return (FRU_FAILURE); 3066bbe0590SSundeep Panicker } 3076bbe0590SSundeep Panicker 3086bbe0590SSundeep Panicker segs = malloc(sizeof (*segs) * (num_seg)); 3096bbe0590SSundeep Panicker if (segs == NULL) { 3106bbe0590SSundeep Panicker return (FRU_FAILURE); 3116bbe0590SSundeep Panicker } 3126bbe0590SSundeep Panicker 3136bbe0590SSundeep Panicker acc_err = fru_get_segments(sect->handle, segs, num_seg, NULL); 3146bbe0590SSundeep Panicker if (acc_err == -1) { 3156bbe0590SSundeep Panicker free(segs); 3166bbe0590SSundeep Panicker return (map_errno(errno)); 3176bbe0590SSundeep Panicker } 3186bbe0590SSundeep Panicker 3196bbe0590SSundeep Panicker for (j = 0; j < num_seg; j++) { 3206bbe0590SSundeep Panicker /* NULL terminate */ 3216bbe0590SSundeep Panicker char tmp[SEG_NAME_LEN+1]; 3226bbe0590SSundeep Panicker (void) memcpy(tmp, segs[j].name, SEG_NAME_LEN); 3236bbe0590SSundeep Panicker tmp[SEG_NAME_LEN] = '\0'; 3246bbe0590SSundeep Panicker if (strcmp(tmp, seg_name) == 0) { 3256bbe0590SSundeep Panicker *segment = segs[j]; 3266bbe0590SSundeep Panicker *prot_flg = (sect->protection ? 1 : 0); 3276bbe0590SSundeep Panicker free(segs); 3286bbe0590SSundeep Panicker return (FRU_SUCCESS); 3296bbe0590SSundeep Panicker } 3306bbe0590SSundeep Panicker } 3316bbe0590SSundeep Panicker 3326bbe0590SSundeep Panicker free(segs); 3336bbe0590SSundeep Panicker return (FRU_INVALSEG); 3346bbe0590SSundeep Panicker } 3356bbe0590SSundeep Panicker 3366bbe0590SSundeep Panicker 3376bbe0590SSundeep Panicker static fru_errno_t 3386bbe0590SSundeep Panicker find_segment(fru_treehdl_t handle, const char *seg_name, int *prot_flg, 3396bbe0590SSundeep Panicker segment_t *segment) 3406bbe0590SSundeep Panicker { 3416bbe0590SSundeep Panicker int i = 0; 3426bbe0590SSundeep Panicker int acc_err = 0; 3436bbe0590SSundeep Panicker section_t *sect = NULL; 3446bbe0590SSundeep Panicker container_hdl_t cont; 3456bbe0590SSundeep Panicker int num_sect; 3466bbe0590SSundeep Panicker 3476bbe0590SSundeep Panicker cont = treehdl_to_conthdl(handle); 3486bbe0590SSundeep Panicker 3496bbe0590SSundeep Panicker num_sect = fru_get_num_sections(cont, NULL); 3506bbe0590SSundeep Panicker if (num_sect == -1) { 3516bbe0590SSundeep Panicker return (map_errno(errno)); 3526bbe0590SSundeep Panicker } 3536bbe0590SSundeep Panicker 3546bbe0590SSundeep Panicker sect = malloc(sizeof (*sect) * (num_sect)); 3556bbe0590SSundeep Panicker if (sect == NULL) { 3566bbe0590SSundeep Panicker return (FRU_FAILURE); 3576bbe0590SSundeep Panicker } 3586bbe0590SSundeep Panicker 3596bbe0590SSundeep Panicker acc_err = fru_get_sections(cont, sect, num_sect, NULL); 3606bbe0590SSundeep Panicker if (acc_err == -1) { 3616bbe0590SSundeep Panicker free(sect); 3626bbe0590SSundeep Panicker return (map_errno(errno)); 3636bbe0590SSundeep Panicker } 3646bbe0590SSundeep Panicker 3656bbe0590SSundeep Panicker for (i = 0; i < num_sect; i++) { 3666bbe0590SSundeep Panicker if (find_seg_in_sect(&(sect[i]), seg_name, prot_flg, segment) 3676bbe0590SSundeep Panicker == FRU_SUCCESS) { 3686bbe0590SSundeep Panicker free(sect); 3696bbe0590SSundeep Panicker return (FRU_SUCCESS); 3706bbe0590SSundeep Panicker } 3716bbe0590SSundeep Panicker } 3726bbe0590SSundeep Panicker 3736bbe0590SSundeep Panicker free(sect); 3746bbe0590SSundeep Panicker return (FRU_INVALSEG); 3756bbe0590SSundeep Panicker } 3766bbe0590SSundeep Panicker 3776bbe0590SSundeep Panicker 3786bbe0590SSundeep Panicker static fru_errno_t 3796bbe0590SSundeep Panicker frt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def) 3806bbe0590SSundeep Panicker { 3816bbe0590SSundeep Panicker fru_errno_t err = FRU_SUCCESS; 3826bbe0590SSundeep Panicker int prot_flg = 0; 3836bbe0590SSundeep Panicker segment_t segment; 3846bbe0590SSundeep Panicker 3856bbe0590SSundeep Panicker if ((err = find_segment(handle, seg_name, &prot_flg, &segment)) 3866bbe0590SSundeep Panicker != FRU_SUCCESS) { 3876bbe0590SSundeep Panicker return (err); 3886bbe0590SSundeep Panicker } 3896bbe0590SSundeep Panicker 3906bbe0590SSundeep Panicker (void) memcpy(def->name, segment.name, SEG_NAME_LEN); 3916bbe0590SSundeep Panicker def->name[SEG_NAME_LEN] = '\0'; 3926bbe0590SSundeep Panicker def->desc.raw_data = segment.descriptor; 3936bbe0590SSundeep Panicker def->size = segment.length; 3946bbe0590SSundeep Panicker def->address = segment.offset; 3956bbe0590SSundeep Panicker 3966bbe0590SSundeep Panicker if (prot_flg == 0) 3976bbe0590SSundeep Panicker def->hw_desc.field.read_only = 0; 3986bbe0590SSundeep Panicker else 3996bbe0590SSundeep Panicker def->hw_desc.field.read_only = 1; 4006bbe0590SSundeep Panicker 4016bbe0590SSundeep Panicker return (FRU_SUCCESS); 4026bbe0590SSundeep Panicker 4036bbe0590SSundeep Panicker } 4046bbe0590SSundeep Panicker 4056bbe0590SSundeep Panicker /* ARGSUSED */ 4066bbe0590SSundeep Panicker static fru_errno_t 4076bbe0590SSundeep Panicker frt_add_seg(fru_treehdl_t handle, fru_segdef_t *def) 4086bbe0590SSundeep Panicker { 4096bbe0590SSundeep Panicker /* NOT SUPPORTED */ 4106bbe0590SSundeep Panicker return (FRU_NOTSUP); 4116bbe0590SSundeep Panicker } 4126bbe0590SSundeep Panicker 4136bbe0590SSundeep Panicker /* ARGSUSED */ 4146bbe0590SSundeep Panicker static fru_errno_t 4156bbe0590SSundeep Panicker frt_delete_seg(fru_treehdl_t handle, const char *seg_name) 4166bbe0590SSundeep Panicker { 4176bbe0590SSundeep Panicker /* NOT SUPPORTED */ 4186bbe0590SSundeep Panicker return (FRU_NOTSUP); 4196bbe0590SSundeep Panicker } 4206bbe0590SSundeep Panicker 4216bbe0590SSundeep Panicker /* ARGSUSED */ 4226bbe0590SSundeep Panicker static fru_errno_t 4236bbe0590SSundeep Panicker frt_for_each_segment(fru_nodehdl_t node, 4246bbe0590SSundeep Panicker int (*function)(fru_seghdl_t hdl, void *args), void *args) 4256bbe0590SSundeep Panicker { 4266bbe0590SSundeep Panicker int num_segment; 4276bbe0590SSundeep Panicker int cnt; 4286bbe0590SSundeep Panicker int num_sect; 4296bbe0590SSundeep Panicker int each_seg; 4306bbe0590SSundeep Panicker section_t *sects; 4316bbe0590SSundeep Panicker segment_t *segs; 4326bbe0590SSundeep Panicker segment_list_t *tmp_list; 4336bbe0590SSundeep Panicker int acc_err; 4346bbe0590SSundeep Panicker int status; 4356bbe0590SSundeep Panicker container_hdl_t cont; 4366bbe0590SSundeep Panicker 4376bbe0590SSundeep Panicker cont = g_raw->cont; 4386bbe0590SSundeep Panicker 4396bbe0590SSundeep Panicker num_sect = fru_get_num_sections(cont, NULL); 4406bbe0590SSundeep Panicker if (num_sect == -1) { 4416bbe0590SSundeep Panicker return (map_errno(errno)); 4426bbe0590SSundeep Panicker } 4436bbe0590SSundeep Panicker 4446bbe0590SSundeep Panicker sects = malloc((num_sect + 1) * sizeof (section_t)); 4456bbe0590SSundeep Panicker if (sects == NULL) { 4466bbe0590SSundeep Panicker return (FRU_FAILURE); 4476bbe0590SSundeep Panicker } 4486bbe0590SSundeep Panicker num_sect = fru_get_sections(cont, sects, num_sect, NULL); 4496bbe0590SSundeep Panicker if (num_sect == -1) { 4506bbe0590SSundeep Panicker free(sects); 4516bbe0590SSundeep Panicker return (map_errno(errno)); 4526bbe0590SSundeep Panicker } 4536bbe0590SSundeep Panicker for (cnt = 0; cnt < num_sect; cnt++) { 4546bbe0590SSundeep Panicker num_segment = fru_get_num_segments(sects[cnt].handle, NULL); 4556bbe0590SSundeep Panicker if (num_segment == -1) { 4566bbe0590SSundeep Panicker return (map_errno(errno)); 4576bbe0590SSundeep Panicker } else if (num_segment == 0) { 4586bbe0590SSundeep Panicker continue; 4596bbe0590SSundeep Panicker } 4606bbe0590SSundeep Panicker segs = malloc((num_segment + 1) * sizeof (segment_t)); 4616bbe0590SSundeep Panicker if (segs == NULL) { 4626bbe0590SSundeep Panicker free(sects); 4636bbe0590SSundeep Panicker return (FRU_FAILURE); 4646bbe0590SSundeep Panicker } 4656bbe0590SSundeep Panicker acc_err = fru_get_segments(sects[cnt].handle, segs, 4666bbe0590SSundeep Panicker num_segment, NULL); 4676bbe0590SSundeep Panicker if (acc_err == -1) { 4686bbe0590SSundeep Panicker free(sects); 4696bbe0590SSundeep Panicker free(segs); 4706bbe0590SSundeep Panicker return (map_errno(errno)); 4716bbe0590SSundeep Panicker } 4726bbe0590SSundeep Panicker for (each_seg = 0; each_seg < num_segment; each_seg++) { 4736bbe0590SSundeep Panicker tmp_list = malloc(sizeof (segment_list_t)); 4746bbe0590SSundeep Panicker tmp_list->segment = &segs[each_seg]; 4756bbe0590SSundeep Panicker tmp_list->next = NULL; 4766bbe0590SSundeep Panicker if (g_raw->segs == NULL) { 4776bbe0590SSundeep Panicker g_raw->segs = tmp_list; 4786bbe0590SSundeep Panicker } else { 4796bbe0590SSundeep Panicker tmp_list->next = g_raw->segs; 4806bbe0590SSundeep Panicker g_raw->segs = tmp_list; 4816bbe0590SSundeep Panicker } 4826bbe0590SSundeep Panicker 4836bbe0590SSundeep Panicker if ((status = function(segs[each_seg].handle, args)) 4846bbe0590SSundeep Panicker != FRU_SUCCESS) { 4856bbe0590SSundeep Panicker free(segs); 4866bbe0590SSundeep Panicker free(sects); 4876bbe0590SSundeep Panicker return (status); 4886bbe0590SSundeep Panicker } 4896bbe0590SSundeep Panicker } 4906bbe0590SSundeep Panicker free(segs); 4916bbe0590SSundeep Panicker free(sects); 4926bbe0590SSundeep Panicker 4936bbe0590SSundeep Panicker } 4946bbe0590SSundeep Panicker return (FRU_SUCCESS); 4956bbe0590SSundeep Panicker } 4966bbe0590SSundeep Panicker 4976bbe0590SSundeep Panicker 4986bbe0590SSundeep Panicker static fru_errno_t 4996bbe0590SSundeep Panicker frt_get_segment_name(fru_seghdl_t node, char **name) 5006bbe0590SSundeep Panicker { 5016bbe0590SSundeep Panicker int num_sect; 5026bbe0590SSundeep Panicker int acc_err; 5036bbe0590SSundeep Panicker int cnt; 5046bbe0590SSundeep Panicker int num_segment; 5056bbe0590SSundeep Panicker section_t *sects; 5066bbe0590SSundeep Panicker segment_t *segs; 5076bbe0590SSundeep Panicker int each_seg; 5086bbe0590SSundeep Panicker container_hdl_t cont; 5096bbe0590SSundeep Panicker 5106bbe0590SSundeep Panicker cont = treehdl_to_conthdl(node); 5116bbe0590SSundeep Panicker 5126bbe0590SSundeep Panicker num_sect = fru_get_num_sections(cont, NULL); 5136bbe0590SSundeep Panicker if (num_sect == -1) { 5146bbe0590SSundeep Panicker return (map_errno(errno)); 5156bbe0590SSundeep Panicker } 5166bbe0590SSundeep Panicker 5176bbe0590SSundeep Panicker sects = malloc(sizeof (*sects) * (num_sect)); 5186bbe0590SSundeep Panicker if (sects == NULL) { 5196bbe0590SSundeep Panicker return (FRU_FAILURE); 5206bbe0590SSundeep Panicker } 5216bbe0590SSundeep Panicker acc_err = fru_get_sections(cont, sects, num_sect, NULL); 5226bbe0590SSundeep Panicker if (acc_err == -1) { 5236bbe0590SSundeep Panicker free(sects); 5246bbe0590SSundeep Panicker return (map_errno(errno)); 5256bbe0590SSundeep Panicker } 5266bbe0590SSundeep Panicker 5276bbe0590SSundeep Panicker for (cnt = 0; cnt < num_sect; cnt++) { 5286bbe0590SSundeep Panicker num_segment = fru_get_num_segments(sects[cnt].handle, NULL); 5296bbe0590SSundeep Panicker if (num_segment == -1) { 5306bbe0590SSundeep Panicker free(sects); 5316bbe0590SSundeep Panicker return (map_errno(errno)); 5326bbe0590SSundeep Panicker } else if (num_segment == 0) { 5336bbe0590SSundeep Panicker continue; 5346bbe0590SSundeep Panicker } 5356bbe0590SSundeep Panicker 5366bbe0590SSundeep Panicker segs = malloc(sizeof (*segs) * (num_segment)); 5376bbe0590SSundeep Panicker if (segs == NULL) { 5386bbe0590SSundeep Panicker free(sects); 5396bbe0590SSundeep Panicker return (FRU_FAILURE); 5406bbe0590SSundeep Panicker } 5416bbe0590SSundeep Panicker 5426bbe0590SSundeep Panicker acc_err = fru_get_segments(sects[cnt].handle, segs, 5436bbe0590SSundeep Panicker num_segment, NULL); 5446bbe0590SSundeep Panicker if (acc_err == -1) { 5456bbe0590SSundeep Panicker free(sects); 5466bbe0590SSundeep Panicker free(segs); 5476bbe0590SSundeep Panicker return (map_errno(errno)); 5486bbe0590SSundeep Panicker } 5496bbe0590SSundeep Panicker 5506bbe0590SSundeep Panicker for (each_seg = 0; each_seg < num_segment; each_seg++) { 5516bbe0590SSundeep Panicker if (segs[each_seg].handle == node) { 5526bbe0590SSundeep Panicker segs[each_seg].name[FRU_SEGNAMELEN] = '\0'; 553*ac88567aSHyon Kim *name = strdup(segs[each_seg].name); 5546bbe0590SSundeep Panicker free(sects); 555*ac88567aSHyon Kim free(segs); 5566bbe0590SSundeep Panicker return (FRU_SUCCESS); 5576bbe0590SSundeep Panicker } 5586bbe0590SSundeep Panicker } 5596bbe0590SSundeep Panicker free(segs); 5606bbe0590SSundeep Panicker } 5616bbe0590SSundeep Panicker 5626bbe0590SSundeep Panicker return (FRU_FAILURE); 5636bbe0590SSundeep Panicker } 5646bbe0590SSundeep Panicker 5656bbe0590SSundeep Panicker 5666bbe0590SSundeep Panicker /* ARGSUSED */ 5676bbe0590SSundeep Panicker static fru_errno_t 5686bbe0590SSundeep Panicker frt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name, 5696bbe0590SSundeep Panicker fru_tag_t tag, uint8_t *data, size_t data_len) 5706bbe0590SSundeep Panicker { 5716bbe0590SSundeep Panicker /* NOT SUPPORTED */ 5726bbe0590SSundeep Panicker return (FRU_NOTSUP); 5736bbe0590SSundeep Panicker } 5746bbe0590SSundeep Panicker 5756bbe0590SSundeep Panicker 5766bbe0590SSundeep Panicker /* ARGSUSED */ 5776bbe0590SSundeep Panicker static fru_errno_t 5786bbe0590SSundeep Panicker frt_get_tag_list(fru_treehdl_t handle, const char *seg_name, 5796bbe0590SSundeep Panicker fru_tag_t **tags, int *number) 5806bbe0590SSundeep Panicker { 5816bbe0590SSundeep Panicker /* NOT SUPPORTED */ 5826bbe0590SSundeep Panicker return (FRU_NOTSUP); 5836bbe0590SSundeep Panicker } 5846bbe0590SSundeep Panicker 5856bbe0590SSundeep Panicker 5866bbe0590SSundeep Panicker /* ARGSUSED */ 5876bbe0590SSundeep Panicker static fru_errno_t 5886bbe0590SSundeep Panicker frt_get_tag_data(fru_treehdl_t handle, const char *seg_name, 5896bbe0590SSundeep Panicker fru_tag_t tag, int instance, 5906bbe0590SSundeep Panicker uint8_t **data, size_t *data_len) 5916bbe0590SSundeep Panicker { 5926bbe0590SSundeep Panicker /* NOT SUPPORTED */ 5936bbe0590SSundeep Panicker return (FRU_NOTSUP); 5946bbe0590SSundeep Panicker } 5956bbe0590SSundeep Panicker 5966bbe0590SSundeep Panicker 5976bbe0590SSundeep Panicker /* ARGSUSED */ 5986bbe0590SSundeep Panicker static fru_errno_t 5996bbe0590SSundeep Panicker frt_set_tag_data(fru_treehdl_t handle, const char *seg_name, 6006bbe0590SSundeep Panicker fru_tag_t tag, int instance, 6016bbe0590SSundeep Panicker uint8_t *data, size_t data_len) 6026bbe0590SSundeep Panicker { 6036bbe0590SSundeep Panicker /* NOT SUPPORTED */ 6046bbe0590SSundeep Panicker return (FRU_NOTSUP); 6056bbe0590SSundeep Panicker } 6066bbe0590SSundeep Panicker 6076bbe0590SSundeep Panicker 6086bbe0590SSundeep Panicker /* ARGSUSED */ 6096bbe0590SSundeep Panicker static fru_errno_t 6106bbe0590SSundeep Panicker frt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag, 6116bbe0590SSundeep Panicker int instance) 6126bbe0590SSundeep Panicker { 6136bbe0590SSundeep Panicker /* NOT SUPPORTED */ 6146bbe0590SSundeep Panicker return (FRU_NOTSUP); 6156bbe0590SSundeep Panicker } 6166bbe0590SSundeep Panicker 6176bbe0590SSundeep Panicker 6186bbe0590SSundeep Panicker static fru_errno_t 6196bbe0590SSundeep Panicker frt_for_each_packet(fru_seghdl_t node, 6206bbe0590SSundeep Panicker int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length, 6216bbe0590SSundeep Panicker void *args), void *args) 6226bbe0590SSundeep Panicker { 6236bbe0590SSundeep Panicker int rc_num; 6246bbe0590SSundeep Panicker int status; 6256bbe0590SSundeep Panicker char *rc_tags; 6266bbe0590SSundeep Panicker char *rc_data; 6276bbe0590SSundeep Panicker int i; 6286bbe0590SSundeep Panicker packet_t *packets = NULL; 6296bbe0590SSundeep Panicker segment_list_t *tmp_list; 6306bbe0590SSundeep Panicker fru_segdesc_t *descriptor; 6316bbe0590SSundeep Panicker 6326bbe0590SSundeep Panicker tmp_list = g_raw->segs; 6336bbe0590SSundeep Panicker 6346bbe0590SSundeep Panicker /* num of packet */ 6356bbe0590SSundeep Panicker rc_num = fru_get_num_packets(node, NULL); 6366bbe0590SSundeep Panicker if (rc_num == -1) { 6376bbe0590SSundeep Panicker return (map_errno(errno)); 6386bbe0590SSundeep Panicker } else if (rc_num == 0) { 6396bbe0590SSundeep Panicker return (FRU_SUCCESS); 6406bbe0590SSundeep Panicker } 6416bbe0590SSundeep Panicker while (tmp_list) { 6426bbe0590SSundeep Panicker if (node == tmp_list->segment->handle) { 6436bbe0590SSundeep Panicker break; 6446bbe0590SSundeep Panicker } 6456bbe0590SSundeep Panicker tmp_list = tmp_list->next; 6466bbe0590SSundeep Panicker } 6476bbe0590SSundeep Panicker if (tmp_list) { 6486bbe0590SSundeep Panicker descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor; 6496bbe0590SSundeep Panicker if (descriptor->field.opaque) { 6506bbe0590SSundeep Panicker return (FRU_SUCCESS); 6516bbe0590SSundeep Panicker } 6526bbe0590SSundeep Panicker 6536bbe0590SSundeep Panicker if (descriptor->field.encrypted && (encrypt_func == NULL)) { 6546bbe0590SSundeep Panicker return (FRU_SUCCESS); 6556bbe0590SSundeep Panicker } 6566bbe0590SSundeep Panicker } 6576bbe0590SSundeep Panicker 6586bbe0590SSundeep Panicker packets = malloc(sizeof (*packets) * (rc_num)); 6596bbe0590SSundeep Panicker if (packets == NULL) { 6606bbe0590SSundeep Panicker return (FRU_FAILURE); 6616bbe0590SSundeep Panicker } 6626bbe0590SSundeep Panicker /* get all packets */ 6636bbe0590SSundeep Panicker if (fru_get_packets(node, packets, rc_num, NULL) == -1) { 6646bbe0590SSundeep Panicker free(packets); 6656bbe0590SSundeep Panicker return (map_errno(errno)); 6666bbe0590SSundeep Panicker } 6676bbe0590SSundeep Panicker 6686bbe0590SSundeep Panicker rc_tags = malloc(sizeof (*rc_tags) * (rc_num)); 6696bbe0590SSundeep Panicker if (rc_tags == NULL) { 6706bbe0590SSundeep Panicker free(packets); 6716bbe0590SSundeep Panicker return (FRU_FAILURE); 6726bbe0590SSundeep Panicker } 6736bbe0590SSundeep Panicker 6746bbe0590SSundeep Panicker /* number of tags */ 6756bbe0590SSundeep Panicker for (i = 0; i < rc_num; i++) { 6766bbe0590SSundeep Panicker size_t rc_len = 6776bbe0590SSundeep Panicker get_payload_length((fru_tag_t *)&packets[i].tag); 6786bbe0590SSundeep Panicker 6796bbe0590SSundeep Panicker rc_data = malloc(sizeof (*rc_data) * (rc_len)); 6806bbe0590SSundeep Panicker if (rc_data == NULL) { 6816bbe0590SSundeep Panicker free(packets); 6826bbe0590SSundeep Panicker return (FRU_FAILURE); 6836bbe0590SSundeep Panicker } 6846bbe0590SSundeep Panicker /* get the payload data */ 6856bbe0590SSundeep Panicker (void) fru_get_payload(packets[i].handle, (void *)rc_data, 6866bbe0590SSundeep Panicker rc_len, NULL); 6876bbe0590SSundeep Panicker 6886bbe0590SSundeep Panicker if (tmp_list) { 6896bbe0590SSundeep Panicker descriptor = 6906bbe0590SSundeep Panicker (fru_segdesc_t *)&tmp_list->segment->descriptor; 6916bbe0590SSundeep Panicker 6926bbe0590SSundeep Panicker if ((descriptor->field.encrypted) && 6936bbe0590SSundeep Panicker ((status = encrypt_func(FRU_DECRYPT, 6946bbe0590SSundeep Panicker (void *)rc_data, rc_len)) 6956bbe0590SSundeep Panicker != FRU_SUCCESS)) { 6966bbe0590SSundeep Panicker return (status); 6976bbe0590SSundeep Panicker } 6986bbe0590SSundeep Panicker } 6996bbe0590SSundeep Panicker /* print packet */ 7006bbe0590SSundeep Panicker if ((status = function((fru_tag_t *)&packets[i].tag, 7016bbe0590SSundeep Panicker (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) { 7026bbe0590SSundeep Panicker free(rc_data); 7036bbe0590SSundeep Panicker free(packets); 7046bbe0590SSundeep Panicker return (status); 7056bbe0590SSundeep Panicker } 7066bbe0590SSundeep Panicker free(rc_data); 7076bbe0590SSundeep Panicker } 7086bbe0590SSundeep Panicker return (FRU_SUCCESS); 7096bbe0590SSundeep Panicker 7106bbe0590SSundeep Panicker } 7116bbe0590SSundeep Panicker 7126bbe0590SSundeep Panicker 7136bbe0590SSundeep Panicker /* object for libfru to link to */ 7146bbe0590SSundeep Panicker fru_datasource_t data_source = 7156bbe0590SSundeep Panicker { 7166bbe0590SSundeep Panicker LIBFRU_DS_VER, 7176bbe0590SSundeep Panicker frt_initialize, 7186bbe0590SSundeep Panicker frt_shutdown, 7196bbe0590SSundeep Panicker frt_get_root, 7206bbe0590SSundeep Panicker frt_get_child, 7216bbe0590SSundeep Panicker frt_get_peer, 7226bbe0590SSundeep Panicker frt_get_parent, 7236bbe0590SSundeep Panicker frt_get_name_from_hdl, 7246bbe0590SSundeep Panicker frt_get_node_type, 7256bbe0590SSundeep Panicker frt_get_seg_list, 7266bbe0590SSundeep Panicker frt_get_seg_def, 7276bbe0590SSundeep Panicker frt_add_seg, 7286bbe0590SSundeep Panicker frt_delete_seg, 7296bbe0590SSundeep Panicker frt_for_each_segment, 7306bbe0590SSundeep Panicker frt_get_segment_name, 7316bbe0590SSundeep Panicker frt_add_tag_to_seg, 7326bbe0590SSundeep Panicker frt_get_tag_list, 7336bbe0590SSundeep Panicker frt_get_tag_data, 7346bbe0590SSundeep Panicker frt_set_tag_data, 7356bbe0590SSundeep Panicker frt_delete_tag, 7366bbe0590SSundeep Panicker frt_for_each_packet 7376bbe0590SSundeep Panicker }; 738