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 <stdlib.h> 29*6bbe0590SSundeep Panicker #include <alloca.h> 30*6bbe0590SSundeep Panicker #include <sys/byteorder.h> 31*6bbe0590SSundeep Panicker #include "fru_access_impl.h" 32*6bbe0590SSundeep Panicker #include "fruraw.h" 33*6bbe0590SSundeep Panicker 34*6bbe0590SSundeep Panicker #pragma init(initialize_raw_access) 35*6bbe0590SSundeep Panicker 36*6bbe0590SSundeep Panicker static hash_obj_t *hash_table[TABLE_SIZE]; 37*6bbe0590SSundeep Panicker extern raw_list_t *g_raw; 38*6bbe0590SSundeep Panicker 39*6bbe0590SSundeep Panicker static void 40*6bbe0590SSundeep Panicker initialize_raw_access(void) 41*6bbe0590SSundeep Panicker { 42*6bbe0590SSundeep Panicker int count; 43*6bbe0590SSundeep Panicker 44*6bbe0590SSundeep Panicker for (count = 0; count < TABLE_SIZE; count++) { 45*6bbe0590SSundeep Panicker hash_table[count] = NULL; 46*6bbe0590SSundeep Panicker } 47*6bbe0590SSundeep Panicker } 48*6bbe0590SSundeep Panicker 49*6bbe0590SSundeep Panicker 50*6bbe0590SSundeep Panicker static hash_obj_t * 51*6bbe0590SSundeep Panicker lookup_handle_object(handle_t handle, int object_type) 52*6bbe0590SSundeep Panicker { 53*6bbe0590SSundeep Panicker handle_t index_to_hash; 54*6bbe0590SSundeep Panicker hash_obj_t *first_hash_obj; 55*6bbe0590SSundeep Panicker hash_obj_t *next_hash_obj; 56*6bbe0590SSundeep Panicker 57*6bbe0590SSundeep Panicker index_to_hash = (handle % TABLE_SIZE); 58*6bbe0590SSundeep Panicker 59*6bbe0590SSundeep Panicker first_hash_obj = hash_table[index_to_hash]; 60*6bbe0590SSundeep Panicker for (next_hash_obj = first_hash_obj; next_hash_obj != NULL; 61*6bbe0590SSundeep Panicker next_hash_obj = next_hash_obj->next) { 62*6bbe0590SSundeep Panicker if ((handle == next_hash_obj->obj_hdl) && 63*6bbe0590SSundeep Panicker (object_type == next_hash_obj->object_type)) { 64*6bbe0590SSundeep Panicker return (next_hash_obj); 65*6bbe0590SSundeep Panicker } 66*6bbe0590SSundeep Panicker } 67*6bbe0590SSundeep Panicker return (NULL); 68*6bbe0590SSundeep Panicker } 69*6bbe0590SSundeep Panicker 70*6bbe0590SSundeep Panicker 71*6bbe0590SSundeep Panicker static void 72*6bbe0590SSundeep Panicker add_hashobject_to_hashtable(hash_obj_t *hash_obj) 73*6bbe0590SSundeep Panicker { 74*6bbe0590SSundeep Panicker handle_t index_to_hash; 75*6bbe0590SSundeep Panicker static uint64_t handle_count = 0; 76*6bbe0590SSundeep Panicker 77*6bbe0590SSundeep Panicker hash_obj->obj_hdl = ++handle_count; /* store the handle */ 78*6bbe0590SSundeep Panicker 79*6bbe0590SSundeep Panicker /* where to add ? */ 80*6bbe0590SSundeep Panicker index_to_hash = ((hash_obj->obj_hdl) % TABLE_SIZE); 81*6bbe0590SSundeep Panicker 82*6bbe0590SSundeep Panicker hash_obj->next = hash_table[index_to_hash]; 83*6bbe0590SSundeep Panicker hash_table[index_to_hash] = hash_obj; /* hash obj. added */ 84*6bbe0590SSundeep Panicker 85*6bbe0590SSundeep Panicker if (hash_obj->next != NULL) { 86*6bbe0590SSundeep Panicker hash_obj->next->prev = hash_obj; 87*6bbe0590SSundeep Panicker } 88*6bbe0590SSundeep Panicker } 89*6bbe0590SSundeep Panicker 90*6bbe0590SSundeep Panicker 91*6bbe0590SSundeep Panicker static hash_obj_t * 92*6bbe0590SSundeep Panicker create_container_hash_object(void) 93*6bbe0590SSundeep Panicker { 94*6bbe0590SSundeep Panicker hash_obj_t *hash_obj; 95*6bbe0590SSundeep Panicker container_obj_t *cont_obj; 96*6bbe0590SSundeep Panicker 97*6bbe0590SSundeep Panicker cont_obj = malloc(sizeof (container_obj_t)); 98*6bbe0590SSundeep Panicker if (cont_obj == NULL) { 99*6bbe0590SSundeep Panicker return (NULL); 100*6bbe0590SSundeep Panicker } 101*6bbe0590SSundeep Panicker 102*6bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t)); 103*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 104*6bbe0590SSundeep Panicker free(cont_obj); 105*6bbe0590SSundeep Panicker return (NULL); 106*6bbe0590SSundeep Panicker } 107*6bbe0590SSundeep Panicker 108*6bbe0590SSundeep Panicker cont_obj->sec_obj_list = NULL; 109*6bbe0590SSundeep Panicker 110*6bbe0590SSundeep Panicker hash_obj->object_type = CONTAINER_TYPE; 111*6bbe0590SSundeep Panicker hash_obj->u.cont_obj = cont_obj; 112*6bbe0590SSundeep Panicker hash_obj->next = NULL; 113*6bbe0590SSundeep Panicker hash_obj->prev = NULL; 114*6bbe0590SSundeep Panicker 115*6bbe0590SSundeep Panicker return (hash_obj); 116*6bbe0590SSundeep Panicker } 117*6bbe0590SSundeep Panicker 118*6bbe0590SSundeep Panicker 119*6bbe0590SSundeep Panicker static hash_obj_t * 120*6bbe0590SSundeep Panicker create_section_hash_object(void) 121*6bbe0590SSundeep Panicker { 122*6bbe0590SSundeep Panicker hash_obj_t *hash_obj; 123*6bbe0590SSundeep Panicker section_obj_t *sec_obj; 124*6bbe0590SSundeep Panicker 125*6bbe0590SSundeep Panicker sec_obj = malloc(sizeof (section_obj_t)); 126*6bbe0590SSundeep Panicker if (sec_obj == NULL) { 127*6bbe0590SSundeep Panicker return (NULL); 128*6bbe0590SSundeep Panicker } 129*6bbe0590SSundeep Panicker 130*6bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t)); 131*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 132*6bbe0590SSundeep Panicker free(sec_obj); 133*6bbe0590SSundeep Panicker return (NULL); 134*6bbe0590SSundeep Panicker } 135*6bbe0590SSundeep Panicker 136*6bbe0590SSundeep Panicker sec_obj->next = NULL; 137*6bbe0590SSundeep Panicker sec_obj->seg_obj_list = NULL; 138*6bbe0590SSundeep Panicker 139*6bbe0590SSundeep Panicker hash_obj->u.sec_obj = sec_obj; 140*6bbe0590SSundeep Panicker hash_obj->object_type = SECTION_TYPE; 141*6bbe0590SSundeep Panicker hash_obj->next = NULL; 142*6bbe0590SSundeep Panicker hash_obj->prev = NULL; 143*6bbe0590SSundeep Panicker 144*6bbe0590SSundeep Panicker return (hash_obj); 145*6bbe0590SSundeep Panicker } 146*6bbe0590SSundeep Panicker 147*6bbe0590SSundeep Panicker 148*6bbe0590SSundeep Panicker static hash_obj_t * 149*6bbe0590SSundeep Panicker create_segment_hash_object(void) 150*6bbe0590SSundeep Panicker { 151*6bbe0590SSundeep Panicker hash_obj_t *hash_obj; 152*6bbe0590SSundeep Panicker segment_obj_t *seg_obj; 153*6bbe0590SSundeep Panicker 154*6bbe0590SSundeep Panicker seg_obj = malloc(sizeof (segment_obj_t)); 155*6bbe0590SSundeep Panicker if (seg_obj == NULL) { 156*6bbe0590SSundeep Panicker return (NULL); 157*6bbe0590SSundeep Panicker } 158*6bbe0590SSundeep Panicker 159*6bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t)); 160*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 161*6bbe0590SSundeep Panicker free(seg_obj); 162*6bbe0590SSundeep Panicker return (NULL); 163*6bbe0590SSundeep Panicker } 164*6bbe0590SSundeep Panicker 165*6bbe0590SSundeep Panicker seg_obj->next = NULL; 166*6bbe0590SSundeep Panicker seg_obj->pkt_obj_list = NULL; 167*6bbe0590SSundeep Panicker 168*6bbe0590SSundeep Panicker hash_obj->object_type = SEGMENT_TYPE; 169*6bbe0590SSundeep Panicker hash_obj->u.seg_obj = seg_obj; 170*6bbe0590SSundeep Panicker hash_obj->next = NULL; 171*6bbe0590SSundeep Panicker hash_obj->prev = NULL; 172*6bbe0590SSundeep Panicker 173*6bbe0590SSundeep Panicker return (hash_obj); 174*6bbe0590SSundeep Panicker } 175*6bbe0590SSundeep Panicker 176*6bbe0590SSundeep Panicker 177*6bbe0590SSundeep Panicker static hash_obj_t * 178*6bbe0590SSundeep Panicker create_packet_hash_object(void) 179*6bbe0590SSundeep Panicker { 180*6bbe0590SSundeep Panicker hash_obj_t *hash_obj; 181*6bbe0590SSundeep Panicker packet_obj_t *pkt_obj; 182*6bbe0590SSundeep Panicker 183*6bbe0590SSundeep Panicker pkt_obj = malloc(sizeof (packet_obj_t)); 184*6bbe0590SSundeep Panicker if (pkt_obj == NULL) { 185*6bbe0590SSundeep Panicker return (NULL); 186*6bbe0590SSundeep Panicker } 187*6bbe0590SSundeep Panicker 188*6bbe0590SSundeep Panicker hash_obj = malloc(sizeof (hash_obj_t)); 189*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 190*6bbe0590SSundeep Panicker free(pkt_obj); 191*6bbe0590SSundeep Panicker return (NULL); 192*6bbe0590SSundeep Panicker } 193*6bbe0590SSundeep Panicker 194*6bbe0590SSundeep Panicker pkt_obj->next = NULL; 195*6bbe0590SSundeep Panicker 196*6bbe0590SSundeep Panicker hash_obj->object_type = PACKET_TYPE; 197*6bbe0590SSundeep Panicker hash_obj->u.pkt_obj = pkt_obj; 198*6bbe0590SSundeep Panicker hash_obj->next = NULL; 199*6bbe0590SSundeep Panicker hash_obj->prev = NULL; 200*6bbe0590SSundeep Panicker 201*6bbe0590SSundeep Panicker return (hash_obj); 202*6bbe0590SSundeep Panicker } 203*6bbe0590SSundeep Panicker 204*6bbe0590SSundeep Panicker 205*6bbe0590SSundeep Panicker 206*6bbe0590SSundeep Panicker static hash_obj_t * 207*6bbe0590SSundeep Panicker get_container_hash_object(int object_type, handle_t handle) 208*6bbe0590SSundeep Panicker { 209*6bbe0590SSundeep Panicker hash_obj_t *hash_obj; 210*6bbe0590SSundeep Panicker 211*6bbe0590SSundeep Panicker switch (object_type) { 212*6bbe0590SSundeep Panicker case CONTAINER_TYPE: 213*6bbe0590SSundeep Panicker break; 214*6bbe0590SSundeep Panicker case SECTION_TYPE: 215*6bbe0590SSundeep Panicker hash_obj = lookup_handle_object(handle, CONTAINER_TYPE); 216*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 217*6bbe0590SSundeep Panicker return (NULL); 218*6bbe0590SSundeep Panicker } 219*6bbe0590SSundeep Panicker break; 220*6bbe0590SSundeep Panicker case SEGMENT_TYPE: 221*6bbe0590SSundeep Panicker hash_obj = lookup_handle_object(handle, SECTION_TYPE); 222*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 223*6bbe0590SSundeep Panicker return (NULL); 224*6bbe0590SSundeep Panicker } 225*6bbe0590SSundeep Panicker hash_obj = lookup_handle_object(hash_obj->u.sec_obj->cont_hdl, 226*6bbe0590SSundeep Panicker CONTAINER_TYPE); 227*6bbe0590SSundeep Panicker break; 228*6bbe0590SSundeep Panicker case PACKET_TYPE: 229*6bbe0590SSundeep Panicker break; 230*6bbe0590SSundeep Panicker default: 231*6bbe0590SSundeep Panicker return (NULL); 232*6bbe0590SSundeep Panicker } 233*6bbe0590SSundeep Panicker 234*6bbe0590SSundeep Panicker return (hash_obj); 235*6bbe0590SSundeep Panicker } 236*6bbe0590SSundeep Panicker 237*6bbe0590SSundeep Panicker 238*6bbe0590SSundeep Panicker static void 239*6bbe0590SSundeep Panicker add_to_pkt_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj) 240*6bbe0590SSundeep Panicker { 241*6bbe0590SSundeep Panicker hash_obj_t *next_hash; 242*6bbe0590SSundeep Panicker 243*6bbe0590SSundeep Panicker /* add the packet object in the end of list */ 244*6bbe0590SSundeep Panicker child_obj->u.pkt_obj->segment_hdl = parent_obj->obj_hdl; 245*6bbe0590SSundeep Panicker 246*6bbe0590SSundeep Panicker if (parent_obj->u.seg_obj->pkt_obj_list == NULL) { 247*6bbe0590SSundeep Panicker parent_obj->u.seg_obj->pkt_obj_list = child_obj; 248*6bbe0590SSundeep Panicker return; 249*6bbe0590SSundeep Panicker } 250*6bbe0590SSundeep Panicker 251*6bbe0590SSundeep Panicker for (next_hash = parent_obj->u.seg_obj->pkt_obj_list; 252*6bbe0590SSundeep Panicker next_hash->u.pkt_obj->next != NULL; 253*6bbe0590SSundeep Panicker next_hash = next_hash->u.pkt_obj->next) { 254*6bbe0590SSundeep Panicker ; 255*6bbe0590SSundeep Panicker } 256*6bbe0590SSundeep Panicker 257*6bbe0590SSundeep Panicker next_hash->u.pkt_obj->next = child_obj; 258*6bbe0590SSundeep Panicker } 259*6bbe0590SSundeep Panicker 260*6bbe0590SSundeep Panicker 261*6bbe0590SSundeep Panicker static void 262*6bbe0590SSundeep Panicker free_pkt_object_list(hash_obj_t *hash_obj) 263*6bbe0590SSundeep Panicker { 264*6bbe0590SSundeep Panicker hash_obj_t *next_obj; 265*6bbe0590SSundeep Panicker hash_obj_t *free_obj; 266*6bbe0590SSundeep Panicker 267*6bbe0590SSundeep Panicker next_obj = hash_obj->u.seg_obj->pkt_obj_list; 268*6bbe0590SSundeep Panicker while (next_obj != NULL) { 269*6bbe0590SSundeep Panicker free_obj = next_obj; 270*6bbe0590SSundeep Panicker next_obj = next_obj->u.pkt_obj->next; 271*6bbe0590SSundeep Panicker /* if prev is NULL it's the first object in the list */ 272*6bbe0590SSundeep Panicker if (free_obj->prev == NULL) { 273*6bbe0590SSundeep Panicker hash_table[(free_obj->obj_hdl % TABLE_SIZE)] = 274*6bbe0590SSundeep Panicker free_obj->next; 275*6bbe0590SSundeep Panicker if (free_obj->next != NULL) { 276*6bbe0590SSundeep Panicker free_obj->next->prev = free_obj->prev; 277*6bbe0590SSundeep Panicker } 278*6bbe0590SSundeep Panicker } else { 279*6bbe0590SSundeep Panicker free_obj->prev->next = free_obj->next; 280*6bbe0590SSundeep Panicker if (free_obj->next != NULL) { 281*6bbe0590SSundeep Panicker free_obj->next->prev = free_obj->prev; 282*6bbe0590SSundeep Panicker } 283*6bbe0590SSundeep Panicker } 284*6bbe0590SSundeep Panicker 285*6bbe0590SSundeep Panicker free(free_obj->u.pkt_obj->payload); 286*6bbe0590SSundeep Panicker free(free_obj->u.pkt_obj); 287*6bbe0590SSundeep Panicker free(free_obj); 288*6bbe0590SSundeep Panicker } 289*6bbe0590SSundeep Panicker 290*6bbe0590SSundeep Panicker hash_obj->u.seg_obj->pkt_obj_list = NULL; 291*6bbe0590SSundeep Panicker } 292*6bbe0590SSundeep Panicker 293*6bbe0590SSundeep Panicker 294*6bbe0590SSundeep Panicker static void 295*6bbe0590SSundeep Panicker free_segment_hash(handle_t handle, hash_obj_t *sec_hash) 296*6bbe0590SSundeep Panicker { 297*6bbe0590SSundeep Panicker hash_obj_t *seg_hash; 298*6bbe0590SSundeep Panicker hash_obj_t *next_hash; 299*6bbe0590SSundeep Panicker 300*6bbe0590SSundeep Panicker seg_hash = sec_hash->u.sec_obj->seg_obj_list; 301*6bbe0590SSundeep Panicker if (seg_hash == NULL) { 302*6bbe0590SSundeep Panicker return; 303*6bbe0590SSundeep Panicker } 304*6bbe0590SSundeep Panicker 305*6bbe0590SSundeep Panicker if (seg_hash->obj_hdl == handle) { 306*6bbe0590SSundeep Panicker sec_hash->u.sec_obj->seg_obj_list = seg_hash->u.seg_obj->next; 307*6bbe0590SSundeep Panicker } else { 308*6bbe0590SSundeep Panicker while (seg_hash->obj_hdl != handle) { 309*6bbe0590SSundeep Panicker next_hash = seg_hash; 310*6bbe0590SSundeep Panicker seg_hash = seg_hash->u.seg_obj->next; 311*6bbe0590SSundeep Panicker if (seg_hash == NULL) { 312*6bbe0590SSundeep Panicker return; 313*6bbe0590SSundeep Panicker } 314*6bbe0590SSundeep Panicker } 315*6bbe0590SSundeep Panicker next_hash->u.seg_obj->next = seg_hash->u.seg_obj->next; 316*6bbe0590SSundeep Panicker } 317*6bbe0590SSundeep Panicker 318*6bbe0590SSundeep Panicker if (seg_hash->prev == NULL) { 319*6bbe0590SSundeep Panicker hash_table[(seg_hash->obj_hdl % TABLE_SIZE)] = seg_hash->next; 320*6bbe0590SSundeep Panicker if (seg_hash->next != NULL) { 321*6bbe0590SSundeep Panicker seg_hash->next->prev = NULL; 322*6bbe0590SSundeep Panicker } 323*6bbe0590SSundeep Panicker } else { 324*6bbe0590SSundeep Panicker seg_hash->prev->next = seg_hash->next; 325*6bbe0590SSundeep Panicker if (seg_hash->next != NULL) { 326*6bbe0590SSundeep Panicker seg_hash->next->prev = seg_hash->prev; 327*6bbe0590SSundeep Panicker } 328*6bbe0590SSundeep Panicker } 329*6bbe0590SSundeep Panicker 330*6bbe0590SSundeep Panicker free_pkt_object_list(seg_hash); 331*6bbe0590SSundeep Panicker free(seg_hash->u.seg_obj); 332*6bbe0590SSundeep Panicker free(seg_hash); 333*6bbe0590SSundeep Panicker } 334*6bbe0590SSundeep Panicker 335*6bbe0590SSundeep Panicker 336*6bbe0590SSundeep Panicker 337*6bbe0590SSundeep Panicker static void 338*6bbe0590SSundeep Panicker add_to_sec_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj) 339*6bbe0590SSundeep Panicker { 340*6bbe0590SSundeep Panicker hash_obj_t *next_hash; 341*6bbe0590SSundeep Panicker 342*6bbe0590SSundeep Panicker child_obj->u.sec_obj->cont_hdl = parent_obj->obj_hdl; 343*6bbe0590SSundeep Panicker if (parent_obj->u.cont_obj->sec_obj_list == NULL) { 344*6bbe0590SSundeep Panicker parent_obj->u.cont_obj->sec_obj_list = child_obj; 345*6bbe0590SSundeep Panicker return; 346*6bbe0590SSundeep Panicker } 347*6bbe0590SSundeep Panicker 348*6bbe0590SSundeep Panicker for (next_hash = parent_obj->u.cont_obj->sec_obj_list; 349*6bbe0590SSundeep Panicker next_hash->u.sec_obj->next != NULL; 350*6bbe0590SSundeep Panicker next_hash = next_hash->u.sec_obj->next) { 351*6bbe0590SSundeep Panicker ; 352*6bbe0590SSundeep Panicker } 353*6bbe0590SSundeep Panicker 354*6bbe0590SSundeep Panicker next_hash->u.sec_obj->next = child_obj; 355*6bbe0590SSundeep Panicker } 356*6bbe0590SSundeep Panicker 357*6bbe0590SSundeep Panicker 358*6bbe0590SSundeep Panicker static void 359*6bbe0590SSundeep Panicker add_to_seg_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj) 360*6bbe0590SSundeep Panicker { 361*6bbe0590SSundeep Panicker hash_obj_t *next_hash; 362*6bbe0590SSundeep Panicker 363*6bbe0590SSundeep Panicker child_obj->u.seg_obj->section_hdl = parent_obj->obj_hdl; 364*6bbe0590SSundeep Panicker if (parent_obj->u.sec_obj->seg_obj_list == NULL) { 365*6bbe0590SSundeep Panicker parent_obj->u.sec_obj->seg_obj_list = child_obj; 366*6bbe0590SSundeep Panicker return; 367*6bbe0590SSundeep Panicker } 368*6bbe0590SSundeep Panicker 369*6bbe0590SSundeep Panicker for (next_hash = parent_obj->u.sec_obj->seg_obj_list; 370*6bbe0590SSundeep Panicker next_hash->u.seg_obj->next != NULL; 371*6bbe0590SSundeep Panicker next_hash = next_hash->u.seg_obj->next) { 372*6bbe0590SSundeep Panicker ; 373*6bbe0590SSundeep Panicker } 374*6bbe0590SSundeep Panicker 375*6bbe0590SSundeep Panicker next_hash->u.seg_obj->next = child_obj; 376*6bbe0590SSundeep Panicker } 377*6bbe0590SSundeep Panicker 378*6bbe0590SSundeep Panicker 379*6bbe0590SSundeep Panicker static char * 380*6bbe0590SSundeep Panicker tokenizer(char *buf, char *separator, char **nextBuf, char *matched) 381*6bbe0590SSundeep Panicker { 382*6bbe0590SSundeep Panicker int i = 0; 383*6bbe0590SSundeep Panicker int j = 0; 384*6bbe0590SSundeep Panicker 385*6bbe0590SSundeep Panicker for (i = 0; buf[i] != '\0'; i++) { 386*6bbe0590SSundeep Panicker for (j = 0; j < strlen(separator); j++) { 387*6bbe0590SSundeep Panicker if (buf[i] == separator[j]) { 388*6bbe0590SSundeep Panicker buf[i] = '\0'; 389*6bbe0590SSundeep Panicker *nextBuf = &(buf[i+1]); 390*6bbe0590SSundeep Panicker *matched = separator[j]; 391*6bbe0590SSundeep Panicker return (buf); 392*6bbe0590SSundeep Panicker } 393*6bbe0590SSundeep Panicker } 394*6bbe0590SSundeep Panicker } 395*6bbe0590SSundeep Panicker 396*6bbe0590SSundeep Panicker *nextBuf = buf; 397*6bbe0590SSundeep Panicker *matched = '\0'; 398*6bbe0590SSundeep Panicker return (NULL); 399*6bbe0590SSundeep Panicker } 400*6bbe0590SSundeep Panicker 401*6bbe0590SSundeep Panicker 402*6bbe0590SSundeep Panicker static void 403*6bbe0590SSundeep Panicker copy_segment_layout(segment_t *seghdr, void *layout) 404*6bbe0590SSundeep Panicker { 405*6bbe0590SSundeep Panicker segment_layout_t *seg_layout; 406*6bbe0590SSundeep Panicker 407*6bbe0590SSundeep Panicker seg_layout = (segment_layout_t *)layout; 408*6bbe0590SSundeep Panicker (void) memcpy(seghdr->name, &seg_layout->name, SEG_NAME_LEN); 409*6bbe0590SSundeep Panicker seghdr->descriptor = GET_SEGMENT_DESCRIPTOR; 410*6bbe0590SSundeep Panicker seghdr->offset = BE_16(seg_layout->offset); 411*6bbe0590SSundeep Panicker seghdr->length = BE_16(seg_layout->length); 412*6bbe0590SSundeep Panicker } 413*6bbe0590SSundeep Panicker 414*6bbe0590SSundeep Panicker 415*6bbe0590SSundeep Panicker static int 416*6bbe0590SSundeep Panicker get_container_info(const char *def_file, const char *cont_desc_str, 417*6bbe0590SSundeep Panicker container_info_t *cont_info) 418*6bbe0590SSundeep Panicker { 419*6bbe0590SSundeep Panicker char *item; 420*6bbe0590SSundeep Panicker char *token; 421*6bbe0590SSundeep Panicker char *field; 422*6bbe0590SSundeep Panicker char matched; 423*6bbe0590SSundeep Panicker char buf[1024]; 424*6bbe0590SSundeep Panicker int foundIt = 0; 425*6bbe0590SSundeep Panicker FILE *file = fopen(def_file, "r"); 426*6bbe0590SSundeep Panicker 427*6bbe0590SSundeep Panicker if (file == NULL) 428*6bbe0590SSundeep Panicker return (-1); 429*6bbe0590SSundeep Panicker 430*6bbe0590SSundeep Panicker cont_info->num_sections = 0; 431*6bbe0590SSundeep Panicker 432*6bbe0590SSundeep Panicker while (fgets(buf, sizeof (buf), file) != NULL) { 433*6bbe0590SSundeep Panicker /* ignore all comments */ 434*6bbe0590SSundeep Panicker token = tokenizer(buf, "#", &field, &matched); 435*6bbe0590SSundeep Panicker /* find the names */ 436*6bbe0590SSundeep Panicker token = tokenizer(buf, ":", &field, &matched); 437*6bbe0590SSundeep Panicker if (token != 0x00) { 438*6bbe0590SSundeep Panicker token = tokenizer(token, "|", &item, &matched); 439*6bbe0590SSundeep Panicker while (token != 0x00) { 440*6bbe0590SSundeep Panicker if (strcmp(token, cont_desc_str) == 0) { 441*6bbe0590SSundeep Panicker foundIt = 1; 442*6bbe0590SSundeep Panicker goto found; 443*6bbe0590SSundeep Panicker } 444*6bbe0590SSundeep Panicker token = tokenizer(item, "|", &item, &matched); 445*6bbe0590SSundeep Panicker } 446*6bbe0590SSundeep Panicker /* check the last remaining item */ 447*6bbe0590SSundeep Panicker if ((item != 0x00) && 448*6bbe0590SSundeep Panicker (strcmp(item, cont_desc_str) == 0)) { 449*6bbe0590SSundeep Panicker foundIt = 1; 450*6bbe0590SSundeep Panicker goto found; 451*6bbe0590SSundeep Panicker } 452*6bbe0590SSundeep Panicker } 453*6bbe0590SSundeep Panicker } 454*6bbe0590SSundeep Panicker 455*6bbe0590SSundeep Panicker found : 456*6bbe0590SSundeep Panicker if (foundIt == 1) { 457*6bbe0590SSundeep Panicker token = tokenizer(field, ":", &field, &matched); 458*6bbe0590SSundeep Panicker if (token == 0x00) { 459*6bbe0590SSundeep Panicker (void) fclose(file); 460*6bbe0590SSundeep Panicker return (-1); 461*6bbe0590SSundeep Panicker } 462*6bbe0590SSundeep Panicker cont_info->header_ver = (headerrev_t)atoi(token); 463*6bbe0590SSundeep Panicker 464*6bbe0590SSundeep Panicker token = tokenizer(field, ":\n", &field, &matched); 465*6bbe0590SSundeep Panicker while (token != 0x00) { 466*6bbe0590SSundeep Panicker token = tokenizer(token, ",", &item, &matched); 467*6bbe0590SSundeep Panicker if (token == 0x00) { 468*6bbe0590SSundeep Panicker (void) fclose(file); 469*6bbe0590SSundeep Panicker return (-1); 470*6bbe0590SSundeep Panicker } 471*6bbe0590SSundeep Panicker if (atoi(token) == 1) { 472*6bbe0590SSundeep Panicker cont_info->section_info[cont_info-> 473*6bbe0590SSundeep Panicker num_sections].description.field.read_only 474*6bbe0590SSundeep Panicker = 1; 475*6bbe0590SSundeep Panicker } else if (atoi(token) == 0) { 476*6bbe0590SSundeep Panicker cont_info->section_info[cont_info-> 477*6bbe0590SSundeep Panicker num_sections].description.field.read_only 478*6bbe0590SSundeep Panicker = 0; 479*6bbe0590SSundeep Panicker } else { 480*6bbe0590SSundeep Panicker (void) fclose(file); 481*6bbe0590SSundeep Panicker return (-1); 482*6bbe0590SSundeep Panicker } 483*6bbe0590SSundeep Panicker 484*6bbe0590SSundeep Panicker token = tokenizer(item, ",", &item, &matched); 485*6bbe0590SSundeep Panicker if (token == 0x00) { 486*6bbe0590SSundeep Panicker (void) fclose(file); 487*6bbe0590SSundeep Panicker return (-1); 488*6bbe0590SSundeep Panicker } 489*6bbe0590SSundeep Panicker 490*6bbe0590SSundeep Panicker cont_info->section_info[cont_info-> 491*6bbe0590SSundeep Panicker num_sections].address = atoi(token); 492*6bbe0590SSundeep Panicker if (item == '\0') { 493*6bbe0590SSundeep Panicker (void) fclose(file); 494*6bbe0590SSundeep Panicker return (-1); 495*6bbe0590SSundeep Panicker } 496*6bbe0590SSundeep Panicker cont_info->section_info[cont_info->num_sections].size = 497*6bbe0590SSundeep Panicker atoi(item); 498*6bbe0590SSundeep Panicker (cont_info->num_sections)++; 499*6bbe0590SSundeep Panicker 500*6bbe0590SSundeep Panicker token = tokenizer(field, ":\n ", &field, &matched); 501*6bbe0590SSundeep Panicker } 502*6bbe0590SSundeep Panicker } 503*6bbe0590SSundeep Panicker (void) fclose(file); 504*6bbe0590SSundeep Panicker 505*6bbe0590SSundeep Panicker return (0); 506*6bbe0590SSundeep Panicker } 507*6bbe0590SSundeep Panicker 508*6bbe0590SSundeep Panicker 509*6bbe0590SSundeep Panicker /* ARGSUSED */ 510*6bbe0590SSundeep Panicker int 511*6bbe0590SSundeep Panicker fru_get_segments(section_hdl_t section, segment_t *segment, int maxseg, 512*6bbe0590SSundeep Panicker door_cred_t *cred) 513*6bbe0590SSundeep Panicker { 514*6bbe0590SSundeep Panicker int count; 515*6bbe0590SSundeep Panicker hash_obj_t *sec_object; 516*6bbe0590SSundeep Panicker hash_obj_t *seg_object; 517*6bbe0590SSundeep Panicker section_obj_t *sec_obj; 518*6bbe0590SSundeep Panicker 519*6bbe0590SSundeep Panicker sec_object = lookup_handle_object(section, SECTION_TYPE); 520*6bbe0590SSundeep Panicker if (sec_object == NULL) { 521*6bbe0590SSundeep Panicker return (-1); 522*6bbe0590SSundeep Panicker } 523*6bbe0590SSundeep Panicker 524*6bbe0590SSundeep Panicker sec_obj = sec_object->u.sec_obj; 525*6bbe0590SSundeep Panicker if (sec_obj == NULL) { 526*6bbe0590SSundeep Panicker return (-1); 527*6bbe0590SSundeep Panicker } 528*6bbe0590SSundeep Panicker 529*6bbe0590SSundeep Panicker if (sec_obj->num_of_segment > maxseg) { 530*6bbe0590SSundeep Panicker return (-1); 531*6bbe0590SSundeep Panicker } 532*6bbe0590SSundeep Panicker 533*6bbe0590SSundeep Panicker seg_object = sec_object->u.sec_obj->seg_obj_list; 534*6bbe0590SSundeep Panicker if (seg_object == NULL) { 535*6bbe0590SSundeep Panicker return (-1); 536*6bbe0590SSundeep Panicker } 537*6bbe0590SSundeep Panicker 538*6bbe0590SSundeep Panicker for (count = 0; count < sec_obj->num_of_segment; count++) { 539*6bbe0590SSundeep Panicker 540*6bbe0590SSundeep Panicker /* populate segment_t */ 541*6bbe0590SSundeep Panicker segment->handle = seg_object->obj_hdl; 542*6bbe0590SSundeep Panicker (void) memcpy(segment->name, 543*6bbe0590SSundeep Panicker seg_object->u.seg_obj->segment.name, SEG_NAME_LEN); 544*6bbe0590SSundeep Panicker segment->descriptor = seg_object->u.seg_obj->segment.descriptor; 545*6bbe0590SSundeep Panicker 546*6bbe0590SSundeep Panicker segment->offset = seg_object->u.seg_obj->segment.offset; 547*6bbe0590SSundeep Panicker segment->length = seg_object->u.seg_obj->segment.length; 548*6bbe0590SSundeep Panicker seg_object = seg_object->u.seg_obj->next; 549*6bbe0590SSundeep Panicker segment++; 550*6bbe0590SSundeep Panicker } 551*6bbe0590SSundeep Panicker return (0); 552*6bbe0590SSundeep Panicker } 553*6bbe0590SSundeep Panicker 554*6bbe0590SSundeep Panicker 555*6bbe0590SSundeep Panicker static int 556*6bbe0590SSundeep Panicker raw_memcpy(void *buffer, raw_list_t *rawlist, int offset, int size) 557*6bbe0590SSundeep Panicker { 558*6bbe0590SSundeep Panicker if (offset + size > rawlist->size) { 559*6bbe0590SSundeep Panicker size = rawlist->size - offset; 560*6bbe0590SSundeep Panicker } 561*6bbe0590SSundeep Panicker 562*6bbe0590SSundeep Panicker (void) memcpy(buffer, &rawlist->raw[offset], size); 563*6bbe0590SSundeep Panicker 564*6bbe0590SSundeep Panicker return (size); 565*6bbe0590SSundeep Panicker } 566*6bbe0590SSundeep Panicker 567*6bbe0590SSundeep Panicker 568*6bbe0590SSundeep Panicker static int 569*6bbe0590SSundeep Panicker verify_header_crc8(headerrev_t head_ver, unsigned char *bytes, int length) 570*6bbe0590SSundeep Panicker { 571*6bbe0590SSundeep Panicker int crc_offset = 0; 572*6bbe0590SSundeep Panicker unsigned char orig_crc8 = 0; 573*6bbe0590SSundeep Panicker unsigned char calc_crc8 = 0; 574*6bbe0590SSundeep Panicker 575*6bbe0590SSundeep Panicker switch (head_ver) { 576*6bbe0590SSundeep Panicker case SECTION_HDR_VER: 577*6bbe0590SSundeep Panicker crc_offset = 4; 578*6bbe0590SSundeep Panicker break; 579*6bbe0590SSundeep Panicker default: 580*6bbe0590SSundeep Panicker errno = EINVAL; 581*6bbe0590SSundeep Panicker return (0); 582*6bbe0590SSundeep Panicker } 583*6bbe0590SSundeep Panicker 584*6bbe0590SSundeep Panicker orig_crc8 = bytes[crc_offset]; 585*6bbe0590SSundeep Panicker bytes[crc_offset] = 0x00; /* clear for calc */ 586*6bbe0590SSundeep Panicker calc_crc8 = compute_crc8(bytes, length); 587*6bbe0590SSundeep Panicker bytes[crc_offset] = orig_crc8; /* restore */ 588*6bbe0590SSundeep Panicker 589*6bbe0590SSundeep Panicker return (orig_crc8 == calc_crc8); 590*6bbe0590SSundeep Panicker } 591*6bbe0590SSundeep Panicker 592*6bbe0590SSundeep Panicker 593*6bbe0590SSundeep Panicker static int 594*6bbe0590SSundeep Panicker get_section(raw_list_t *rawlist, hash_obj_t *sec_hash, section_t *section) 595*6bbe0590SSundeep Panicker { 596*6bbe0590SSundeep Panicker int retval; 597*6bbe0590SSundeep Panicker int size; 598*6bbe0590SSundeep Panicker int count; 599*6bbe0590SSundeep Panicker uint16_t hdrver; 600*6bbe0590SSundeep Panicker hash_obj_t *seg_hash; 601*6bbe0590SSundeep Panicker unsigned char *buffer; 602*6bbe0590SSundeep Panicker section_obj_t *sec_obj; 603*6bbe0590SSundeep Panicker section_layout_t sec_hdr; 604*6bbe0590SSundeep Panicker segment_layout_t *seg_hdr; 605*6bbe0590SSundeep Panicker segment_layout_t *seg_buf; 606*6bbe0590SSundeep Panicker 607*6bbe0590SSundeep Panicker sec_obj = sec_hash->u.sec_obj; 608*6bbe0590SSundeep Panicker if (sec_obj == NULL) { 609*6bbe0590SSundeep Panicker return (-1); 610*6bbe0590SSundeep Panicker } 611*6bbe0590SSundeep Panicker 612*6bbe0590SSundeep Panicker /* populate section_t */ 613*6bbe0590SSundeep Panicker section->handle = sec_hash->obj_hdl; 614*6bbe0590SSundeep Panicker section->offset = sec_obj->section.offset; 615*6bbe0590SSundeep Panicker section->length = sec_obj->section.length; 616*6bbe0590SSundeep Panicker section->protection = sec_obj->section.protection; 617*6bbe0590SSundeep Panicker section->version = sec_obj->section.version; 618*6bbe0590SSundeep Panicker 619*6bbe0590SSundeep Panicker /* read section header layout */ 620*6bbe0590SSundeep Panicker retval = raw_memcpy(&sec_hdr, rawlist, sec_obj->section.offset, 621*6bbe0590SSundeep Panicker sizeof (sec_hdr)); 622*6bbe0590SSundeep Panicker 623*6bbe0590SSundeep Panicker if (retval != sizeof (sec_hdr)) { 624*6bbe0590SSundeep Panicker return (-1); 625*6bbe0590SSundeep Panicker } 626*6bbe0590SSundeep Panicker 627*6bbe0590SSundeep Panicker 628*6bbe0590SSundeep Panicker hdrver = GET_SECTION_HDR_VERSION; 629*6bbe0590SSundeep Panicker 630*6bbe0590SSundeep Panicker if ((sec_hdr.headertag != SECTION_HDR_TAG) && 631*6bbe0590SSundeep Panicker (hdrver != section->version)) { 632*6bbe0590SSundeep Panicker return (-1); 633*6bbe0590SSundeep Panicker } 634*6bbe0590SSundeep Panicker 635*6bbe0590SSundeep Panicker /* size = section layout + total sizeof segment header */ 636*6bbe0590SSundeep Panicker size = sizeof (sec_hdr) + ((sec_hdr.segmentcount) 637*6bbe0590SSundeep Panicker * sizeof (segment_layout_t)); 638*6bbe0590SSundeep Panicker 639*6bbe0590SSundeep Panicker buffer = alloca(size); 640*6bbe0590SSundeep Panicker if (buffer == NULL) { 641*6bbe0590SSundeep Panicker return (-1); 642*6bbe0590SSundeep Panicker } 643*6bbe0590SSundeep Panicker 644*6bbe0590SSundeep Panicker /* segment header buffer */ 645*6bbe0590SSundeep Panicker seg_buf = alloca(size - sizeof (sec_hdr)); 646*6bbe0590SSundeep Panicker if (seg_buf == NULL) { 647*6bbe0590SSundeep Panicker return (-1); 648*6bbe0590SSundeep Panicker } 649*6bbe0590SSundeep Panicker 650*6bbe0590SSundeep Panicker /* read segment header */ 651*6bbe0590SSundeep Panicker retval = raw_memcpy(seg_buf, rawlist, 652*6bbe0590SSundeep Panicker sec_obj->section.offset + sizeof (sec_hdr), 653*6bbe0590SSundeep Panicker size - sizeof (sec_hdr)); 654*6bbe0590SSundeep Panicker 655*6bbe0590SSundeep Panicker if (retval != (size - sizeof (sec_hdr))) { 656*6bbe0590SSundeep Panicker return (-1); 657*6bbe0590SSundeep Panicker } 658*6bbe0590SSundeep Panicker 659*6bbe0590SSundeep Panicker /* copy section header layout */ 660*6bbe0590SSundeep Panicker (void) memcpy(buffer, &sec_hdr, sizeof (sec_hdr)); 661*6bbe0590SSundeep Panicker 662*6bbe0590SSundeep Panicker /* copy segment header layout */ 663*6bbe0590SSundeep Panicker (void) memcpy(buffer + sizeof (sec_hdr), seg_buf, size - 664*6bbe0590SSundeep Panicker sizeof (sec_hdr)); 665*6bbe0590SSundeep Panicker 666*6bbe0590SSundeep Panicker /* verify crc8 */ 667*6bbe0590SSundeep Panicker retval = verify_header_crc8(hdrver, buffer, size); 668*6bbe0590SSundeep Panicker if (retval != TRUE) { 669*6bbe0590SSundeep Panicker return (-1); 670*6bbe0590SSundeep Panicker } 671*6bbe0590SSundeep Panicker 672*6bbe0590SSundeep Panicker section->version = hdrver; 673*6bbe0590SSundeep Panicker sec_obj->section.version = hdrver; 674*6bbe0590SSundeep Panicker 675*6bbe0590SSundeep Panicker seg_hdr = (segment_layout_t *)seg_buf; 676*6bbe0590SSundeep Panicker 677*6bbe0590SSundeep Panicker /* bug fix for frutool */ 678*6bbe0590SSundeep Panicker if (sec_hash->u.sec_obj->seg_obj_list != NULL) { 679*6bbe0590SSundeep Panicker return (0); 680*6bbe0590SSundeep Panicker } else { 681*6bbe0590SSundeep Panicker sec_obj->num_of_segment = 0; 682*6bbe0590SSundeep Panicker } 683*6bbe0590SSundeep Panicker for (count = 0; count < sec_hdr.segmentcount; count++, seg_hdr++) { 684*6bbe0590SSundeep Panicker 685*6bbe0590SSundeep Panicker seg_hash = create_segment_hash_object(); 686*6bbe0590SSundeep Panicker if (seg_hash == NULL) { 687*6bbe0590SSundeep Panicker return (-1); 688*6bbe0590SSundeep Panicker } 689*6bbe0590SSundeep Panicker add_hashobject_to_hashtable(seg_hash); 690*6bbe0590SSundeep Panicker copy_segment_layout(&seg_hash->u.seg_obj->segment, seg_hdr); 691*6bbe0590SSundeep Panicker add_to_seg_object_list(sec_hash, seg_hash); 692*6bbe0590SSundeep Panicker sec_obj->num_of_segment++; 693*6bbe0590SSundeep Panicker } 694*6bbe0590SSundeep Panicker return (0); 695*6bbe0590SSundeep Panicker } 696*6bbe0590SSundeep Panicker 697*6bbe0590SSundeep Panicker /* ARGSUSED */ 698*6bbe0590SSundeep Panicker int 699*6bbe0590SSundeep Panicker fru_get_sections(container_hdl_t container, section_t *section, int maxsec, 700*6bbe0590SSundeep Panicker door_cred_t *cred) 701*6bbe0590SSundeep Panicker { 702*6bbe0590SSundeep Panicker int count; 703*6bbe0590SSundeep Panicker int num_sec = 0; 704*6bbe0590SSundeep Panicker hash_obj_t *cont_object; 705*6bbe0590SSundeep Panicker hash_obj_t *sec_hash; 706*6bbe0590SSundeep Panicker 707*6bbe0590SSundeep Panicker cont_object = lookup_handle_object(container, CONTAINER_TYPE); 708*6bbe0590SSundeep Panicker if (cont_object == NULL) { 709*6bbe0590SSundeep Panicker return (-1); 710*6bbe0590SSundeep Panicker } 711*6bbe0590SSundeep Panicker 712*6bbe0590SSundeep Panicker if (cont_object->u.cont_obj->num_of_section > maxsec) { 713*6bbe0590SSundeep Panicker return (-1); 714*6bbe0590SSundeep Panicker } 715*6bbe0590SSundeep Panicker 716*6bbe0590SSundeep Panicker sec_hash = cont_object->u.cont_obj->sec_obj_list; 717*6bbe0590SSundeep Panicker if (sec_hash == NULL) { 718*6bbe0590SSundeep Panicker return (-1); 719*6bbe0590SSundeep Panicker } 720*6bbe0590SSundeep Panicker 721*6bbe0590SSundeep Panicker for (count = 0; count < cont_object->u.cont_obj->num_of_section; 722*6bbe0590SSundeep Panicker count++) { 723*6bbe0590SSundeep Panicker section->version = -1; 724*6bbe0590SSundeep Panicker /* populate section_t */ 725*6bbe0590SSundeep Panicker if (get_section(g_raw, sec_hash, section) == 0) { 726*6bbe0590SSundeep Panicker section++; 727*6bbe0590SSundeep Panicker num_sec++; 728*6bbe0590SSundeep Panicker } 729*6bbe0590SSundeep Panicker sec_hash = sec_hash->u.sec_obj->next; 730*6bbe0590SSundeep Panicker } 731*6bbe0590SSundeep Panicker return (num_sec); 732*6bbe0590SSundeep Panicker } 733*6bbe0590SSundeep Panicker 734*6bbe0590SSundeep Panicker 735*6bbe0590SSundeep Panicker static uint32_t 736*6bbe0590SSundeep Panicker get_checksum_crc(hash_obj_t *seg_hash, int data_size) 737*6bbe0590SSundeep Panicker { 738*6bbe0590SSundeep Panicker int protection; 739*6bbe0590SSundeep Panicker int offset = 0; 740*6bbe0590SSundeep Panicker uint32_t crc; 741*6bbe0590SSundeep Panicker hash_obj_t *sec_hash; 742*6bbe0590SSundeep Panicker hash_obj_t *pkt_hash; 743*6bbe0590SSundeep Panicker unsigned char *buffer; 744*6bbe0590SSundeep Panicker 745*6bbe0590SSundeep Panicker sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl, 746*6bbe0590SSundeep Panicker SECTION_TYPE); 747*6bbe0590SSundeep Panicker if (sec_hash == NULL) { 748*6bbe0590SSundeep Panicker return ((uint32_t)-1); 749*6bbe0590SSundeep Panicker } 750*6bbe0590SSundeep Panicker 751*6bbe0590SSundeep Panicker buffer = alloca(data_size); 752*6bbe0590SSundeep Panicker if (buffer == NULL) { 753*6bbe0590SSundeep Panicker return ((uint32_t)-1); 754*6bbe0590SSundeep Panicker } 755*6bbe0590SSundeep Panicker 756*6bbe0590SSundeep Panicker /* traverse the packet object list for all the tags and payload */ 757*6bbe0590SSundeep Panicker for (pkt_hash = seg_hash->u.seg_obj->pkt_obj_list; pkt_hash != NULL; 758*6bbe0590SSundeep Panicker pkt_hash = pkt_hash->u.pkt_obj->next) { 759*6bbe0590SSundeep Panicker (void) memcpy(buffer + offset, &pkt_hash->u.pkt_obj->tag, 760*6bbe0590SSundeep Panicker pkt_hash->u.pkt_obj->tag_size); 761*6bbe0590SSundeep Panicker offset += pkt_hash->u.pkt_obj->tag_size; 762*6bbe0590SSundeep Panicker (void) memcpy(buffer + offset, pkt_hash->u.pkt_obj->payload, 763*6bbe0590SSundeep Panicker pkt_hash->u.pkt_obj->paylen); 764*6bbe0590SSundeep Panicker offset += pkt_hash->u.pkt_obj->paylen; 765*6bbe0590SSundeep Panicker } 766*6bbe0590SSundeep Panicker 767*6bbe0590SSundeep Panicker protection = sec_hash->u.sec_obj->section.protection; 768*6bbe0590SSundeep Panicker 769*6bbe0590SSundeep Panicker if (protection == READ_ONLY_SECTION) { /* read-only section */ 770*6bbe0590SSundeep Panicker crc = compute_crc32(buffer, data_size); 771*6bbe0590SSundeep Panicker } else { /* read/write section */ 772*6bbe0590SSundeep Panicker crc = compute_checksum32(buffer, data_size); 773*6bbe0590SSundeep Panicker } 774*6bbe0590SSundeep Panicker return (crc); /* computed crc */ 775*6bbe0590SSundeep Panicker } 776*6bbe0590SSundeep Panicker 777*6bbe0590SSundeep Panicker 778*6bbe0590SSundeep Panicker static int 779*6bbe0590SSundeep Panicker get_packet(raw_list_t *rawlist, void *buffer, int size, int offset) 780*6bbe0590SSundeep Panicker { 781*6bbe0590SSundeep Panicker int retval; 782*6bbe0590SSundeep Panicker 783*6bbe0590SSundeep Panicker retval = raw_memcpy(buffer, rawlist, offset, size); 784*6bbe0590SSundeep Panicker 785*6bbe0590SSundeep Panicker if (retval != -1) { 786*6bbe0590SSundeep Panicker return (0); 787*6bbe0590SSundeep Panicker } 788*6bbe0590SSundeep Panicker return (-1); 789*6bbe0590SSundeep Panicker } 790*6bbe0590SSundeep Panicker 791*6bbe0590SSundeep Panicker 792*6bbe0590SSundeep Panicker static int 793*6bbe0590SSundeep Panicker get_packets(hash_obj_t *seg_hash, raw_list_t *rawlist, int offset, int length) 794*6bbe0590SSundeep Panicker { 795*6bbe0590SSundeep Panicker int tag_size; 796*6bbe0590SSundeep Panicker int paylen; 797*6bbe0590SSundeep Panicker int retval; 798*6bbe0590SSundeep Panicker int seg_limit = 0; 799*6bbe0590SSundeep Panicker int pktcnt = 0; 800*6bbe0590SSundeep Panicker char *data; 801*6bbe0590SSundeep Panicker uint32_t crc; 802*6bbe0590SSundeep Panicker uint32_t origcrc; 803*6bbe0590SSundeep Panicker fru_tag_t tag; 804*6bbe0590SSundeep Panicker hash_obj_t *pkt_hash_obj; 805*6bbe0590SSundeep Panicker hash_obj_t *sec_hash; 806*6bbe0590SSundeep Panicker fru_segdesc_t *segdesc; 807*6bbe0590SSundeep Panicker fru_tagtype_t tagtype; 808*6bbe0590SSundeep Panicker char *ignore_flag; 809*6bbe0590SSundeep Panicker 810*6bbe0590SSundeep Panicker retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), offset); 811*6bbe0590SSundeep Panicker if (retval == -1) { 812*6bbe0590SSundeep Panicker return (-1); 813*6bbe0590SSundeep Panicker } 814*6bbe0590SSundeep Panicker 815*6bbe0590SSundeep Panicker /* section hash object */ 816*6bbe0590SSundeep Panicker sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl, 817*6bbe0590SSundeep Panicker SECTION_TYPE); 818*6bbe0590SSundeep Panicker 819*6bbe0590SSundeep Panicker if (sec_hash == NULL) { 820*6bbe0590SSundeep Panicker return (-1); 821*6bbe0590SSundeep Panicker } 822*6bbe0590SSundeep Panicker 823*6bbe0590SSundeep Panicker seg_hash->u.seg_obj->trailer_offset = offset; 824*6bbe0590SSundeep Panicker 825*6bbe0590SSundeep Panicker data = (char *)&tag; 826*6bbe0590SSundeep Panicker while (data[0] != SEG_TRAILER_TAG) { 827*6bbe0590SSundeep Panicker tagtype = get_tag_type(&tag); /* verify tag type */ 828*6bbe0590SSundeep Panicker if (tagtype == -1) { 829*6bbe0590SSundeep Panicker return (-1); 830*6bbe0590SSundeep Panicker } 831*6bbe0590SSundeep Panicker 832*6bbe0590SSundeep Panicker tag_size = get_tag_size(tagtype); 833*6bbe0590SSundeep Panicker if (tag_size == -1) { 834*6bbe0590SSundeep Panicker return (-1); 835*6bbe0590SSundeep Panicker } 836*6bbe0590SSundeep Panicker 837*6bbe0590SSundeep Panicker seg_limit += tag_size; 838*6bbe0590SSundeep Panicker if (seg_limit > length) { 839*6bbe0590SSundeep Panicker return (-1); 840*6bbe0590SSundeep Panicker } 841*6bbe0590SSundeep Panicker 842*6bbe0590SSundeep Panicker paylen = get_payload_length((void *)&tag); 843*6bbe0590SSundeep Panicker if (paylen == -1) { 844*6bbe0590SSundeep Panicker return (-1); 845*6bbe0590SSundeep Panicker } 846*6bbe0590SSundeep Panicker 847*6bbe0590SSundeep Panicker seg_limit += paylen; 848*6bbe0590SSundeep Panicker if (seg_limit > length) { 849*6bbe0590SSundeep Panicker return (-1); 850*6bbe0590SSundeep Panicker } 851*6bbe0590SSundeep Panicker if ((offset + tag_size + paylen) > 852*6bbe0590SSundeep Panicker (sec_hash->u.sec_obj->section.offset + 853*6bbe0590SSundeep Panicker sec_hash->u.sec_obj->section.length)) { 854*6bbe0590SSundeep Panicker return (-1); 855*6bbe0590SSundeep Panicker } 856*6bbe0590SSundeep Panicker 857*6bbe0590SSundeep Panicker pkt_hash_obj = create_packet_hash_object(); 858*6bbe0590SSundeep Panicker if (pkt_hash_obj == NULL) { 859*6bbe0590SSundeep Panicker return (-1); 860*6bbe0590SSundeep Panicker } 861*6bbe0590SSundeep Panicker 862*6bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->payload = malloc(paylen); 863*6bbe0590SSundeep Panicker if (pkt_hash_obj->u.pkt_obj->payload == NULL) { 864*6bbe0590SSundeep Panicker free(pkt_hash_obj); 865*6bbe0590SSundeep Panicker return (-1); 866*6bbe0590SSundeep Panicker } 867*6bbe0590SSundeep Panicker 868*6bbe0590SSundeep Panicker offset += tag_size; 869*6bbe0590SSundeep Panicker 870*6bbe0590SSundeep Panicker retval = raw_memcpy(pkt_hash_obj->u.pkt_obj->payload, rawlist, 871*6bbe0590SSundeep Panicker offset, paylen); 872*6bbe0590SSundeep Panicker 873*6bbe0590SSundeep Panicker if (retval != paylen) { 874*6bbe0590SSundeep Panicker free(pkt_hash_obj->u.pkt_obj->payload); 875*6bbe0590SSundeep Panicker free(pkt_hash_obj); 876*6bbe0590SSundeep Panicker return (-1); 877*6bbe0590SSundeep Panicker } 878*6bbe0590SSundeep Panicker 879*6bbe0590SSundeep Panicker /* don't change this */ 880*6bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->tag.raw_data = 0; 881*6bbe0590SSundeep Panicker (void) memcpy(&pkt_hash_obj->u.pkt_obj->tag, &tag, tag_size); 882*6bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->paylen = paylen; 883*6bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->tag_size = tag_size; 884*6bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->payload_offset = offset; 885*6bbe0590SSundeep Panicker 886*6bbe0590SSundeep Panicker offset += paylen; 887*6bbe0590SSundeep Panicker 888*6bbe0590SSundeep Panicker add_hashobject_to_hashtable(pkt_hash_obj); 889*6bbe0590SSundeep Panicker add_to_pkt_object_list(seg_hash, pkt_hash_obj); 890*6bbe0590SSundeep Panicker 891*6bbe0590SSundeep Panicker pktcnt++; 892*6bbe0590SSundeep Panicker 893*6bbe0590SSundeep Panicker retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), 894*6bbe0590SSundeep Panicker offset); 895*6bbe0590SSundeep Panicker if (retval == -1) { 896*6bbe0590SSundeep Panicker return (retval); 897*6bbe0590SSundeep Panicker } 898*6bbe0590SSundeep Panicker 899*6bbe0590SSundeep Panicker data = (char *)&tag; 900*6bbe0590SSundeep Panicker } 901*6bbe0590SSundeep Panicker 902*6bbe0590SSundeep Panicker segdesc = (fru_segdesc_t *)&seg_hash->u.seg_obj->segment.descriptor; 903*6bbe0590SSundeep Panicker 904*6bbe0590SSundeep Panicker seg_hash->u.seg_obj->trailer_offset = offset; 905*6bbe0590SSundeep Panicker 906*6bbe0590SSundeep Panicker if (!segdesc->field.ignore_checksum) { 907*6bbe0590SSundeep Panicker crc = get_checksum_crc(seg_hash, seg_limit); 908*6bbe0590SSundeep Panicker offset = seg_hash->u.seg_obj->segment.offset; 909*6bbe0590SSundeep Panicker 910*6bbe0590SSundeep Panicker retval = raw_memcpy(&origcrc, rawlist, offset + seg_limit + 1, 911*6bbe0590SSundeep Panicker sizeof (origcrc)); 912*6bbe0590SSundeep Panicker 913*6bbe0590SSundeep Panicker ignore_flag = getenv(IGNORE_CHECK); 914*6bbe0590SSundeep Panicker if (ignore_flag != NULL) { 915*6bbe0590SSundeep Panicker return (pktcnt); 916*6bbe0590SSundeep Panicker } 917*6bbe0590SSundeep Panicker 918*6bbe0590SSundeep Panicker if (retval != sizeof (origcrc)) { 919*6bbe0590SSundeep Panicker return (-1); 920*6bbe0590SSundeep Panicker } 921*6bbe0590SSundeep Panicker 922*6bbe0590SSundeep Panicker origcrc = BE_32(origcrc); 923*6bbe0590SSundeep Panicker if (origcrc != crc) { 924*6bbe0590SSundeep Panicker seg_hash->u.seg_obj->trailer_offset = offset; 925*6bbe0590SSundeep Panicker return (-1); 926*6bbe0590SSundeep Panicker } 927*6bbe0590SSundeep Panicker } 928*6bbe0590SSundeep Panicker 929*6bbe0590SSundeep Panicker return (pktcnt); 930*6bbe0590SSundeep Panicker } 931*6bbe0590SSundeep Panicker 932*6bbe0590SSundeep Panicker /* ARGSUSED */ 933*6bbe0590SSundeep Panicker int 934*6bbe0590SSundeep Panicker fru_get_num_sections(container_hdl_t container, door_cred_t *cred) 935*6bbe0590SSundeep Panicker { 936*6bbe0590SSundeep Panicker hash_obj_t *hash_object; 937*6bbe0590SSundeep Panicker 938*6bbe0590SSundeep Panicker hash_object = lookup_handle_object(container, CONTAINER_TYPE); 939*6bbe0590SSundeep Panicker if (hash_object == NULL) { 940*6bbe0590SSundeep Panicker return (-1); 941*6bbe0590SSundeep Panicker } 942*6bbe0590SSundeep Panicker 943*6bbe0590SSundeep Panicker return (hash_object->u.cont_obj->num_of_section); 944*6bbe0590SSundeep Panicker } 945*6bbe0590SSundeep Panicker 946*6bbe0590SSundeep Panicker /* ARGSUSED */ 947*6bbe0590SSundeep Panicker int 948*6bbe0590SSundeep Panicker fru_get_num_segments(section_hdl_t section, door_cred_t *cred) 949*6bbe0590SSundeep Panicker { 950*6bbe0590SSundeep Panicker hash_obj_t *sec_object; 951*6bbe0590SSundeep Panicker section_obj_t *sec_obj; 952*6bbe0590SSundeep Panicker 953*6bbe0590SSundeep Panicker sec_object = lookup_handle_object(section, SECTION_TYPE); 954*6bbe0590SSundeep Panicker if (sec_object == NULL) { 955*6bbe0590SSundeep Panicker return (-1); 956*6bbe0590SSundeep Panicker } 957*6bbe0590SSundeep Panicker 958*6bbe0590SSundeep Panicker sec_obj = sec_object->u.sec_obj; 959*6bbe0590SSundeep Panicker if (sec_obj == NULL) { 960*6bbe0590SSundeep Panicker return (-1); 961*6bbe0590SSundeep Panicker } 962*6bbe0590SSundeep Panicker 963*6bbe0590SSundeep Panicker return (sec_obj->num_of_segment); 964*6bbe0590SSundeep Panicker } 965*6bbe0590SSundeep Panicker 966*6bbe0590SSundeep Panicker /* ARGSUSED */ 967*6bbe0590SSundeep Panicker int 968*6bbe0590SSundeep Panicker fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred) 969*6bbe0590SSundeep Panicker { 970*6bbe0590SSundeep Panicker int pktcnt; 971*6bbe0590SSundeep Panicker int length; 972*6bbe0590SSundeep Panicker uint16_t offset; 973*6bbe0590SSundeep Panicker hash_obj_t *cont_hash_obj; 974*6bbe0590SSundeep Panicker hash_obj_t *seg_hash; 975*6bbe0590SSundeep Panicker hash_obj_t *sec_hash; 976*6bbe0590SSundeep Panicker fru_segdesc_t *segdesc; 977*6bbe0590SSundeep Panicker segment_obj_t *segment_object; 978*6bbe0590SSundeep Panicker 979*6bbe0590SSundeep Panicker seg_hash = lookup_handle_object(segment, SEGMENT_TYPE); 980*6bbe0590SSundeep Panicker if (seg_hash == NULL) { 981*6bbe0590SSundeep Panicker return (-1); 982*6bbe0590SSundeep Panicker } 983*6bbe0590SSundeep Panicker 984*6bbe0590SSundeep Panicker segment_object = seg_hash->u.seg_obj; 985*6bbe0590SSundeep Panicker if (segment_object == NULL) { 986*6bbe0590SSundeep Panicker return (-1); 987*6bbe0590SSundeep Panicker } 988*6bbe0590SSundeep Panicker 989*6bbe0590SSundeep Panicker segdesc = (fru_segdesc_t *)&segment_object->segment.descriptor; 990*6bbe0590SSundeep Panicker if (segdesc->field.opaque) { 991*6bbe0590SSundeep Panicker return (0); 992*6bbe0590SSundeep Panicker } 993*6bbe0590SSundeep Panicker 994*6bbe0590SSundeep Panicker offset = segment_object->segment.offset; 995*6bbe0590SSundeep Panicker length = segment_object->segment.length; 996*6bbe0590SSundeep Panicker 997*6bbe0590SSundeep Panicker cont_hash_obj = get_container_hash_object(SEGMENT_TYPE, 998*6bbe0590SSundeep Panicker segment_object->section_hdl); 999*6bbe0590SSundeep Panicker 1000*6bbe0590SSundeep Panicker if (cont_hash_obj == NULL) { 1001*6bbe0590SSundeep Panicker return (-1); 1002*6bbe0590SSundeep Panicker } 1003*6bbe0590SSundeep Panicker 1004*6bbe0590SSundeep Panicker if (seg_hash->u.seg_obj->pkt_obj_list != NULL) { 1005*6bbe0590SSundeep Panicker return (segment_object->num_of_packets); 1006*6bbe0590SSundeep Panicker } 1007*6bbe0590SSundeep Panicker /* section hash object */ 1008*6bbe0590SSundeep Panicker sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl, 1009*6bbe0590SSundeep Panicker SECTION_TYPE); 1010*6bbe0590SSundeep Panicker if (sec_hash == NULL) { 1011*6bbe0590SSundeep Panicker return (-1); 1012*6bbe0590SSundeep Panicker } 1013*6bbe0590SSundeep Panicker 1014*6bbe0590SSundeep Panicker /* valid segment header b'cos crc8 already validated */ 1015*6bbe0590SSundeep Panicker if (offset < sec_hash->u.sec_obj->section.offset) { 1016*6bbe0590SSundeep Panicker return (-1); 1017*6bbe0590SSundeep Panicker } 1018*6bbe0590SSundeep Panicker 1019*6bbe0590SSundeep Panicker segment_object->num_of_packets = 0; 1020*6bbe0590SSundeep Panicker 1021*6bbe0590SSundeep Panicker pktcnt = get_packets(seg_hash, g_raw, offset, length); 1022*6bbe0590SSundeep Panicker if (pktcnt == -1) { 1023*6bbe0590SSundeep Panicker free_pkt_object_list(seg_hash); 1024*6bbe0590SSundeep Panicker seg_hash->u.seg_obj->pkt_obj_list = NULL; 1025*6bbe0590SSundeep Panicker } 1026*6bbe0590SSundeep Panicker 1027*6bbe0590SSundeep Panicker segment_object->num_of_packets = pktcnt; 1028*6bbe0590SSundeep Panicker 1029*6bbe0590SSundeep Panicker return (segment_object->num_of_packets); 1030*6bbe0590SSundeep Panicker } 1031*6bbe0590SSundeep Panicker 1032*6bbe0590SSundeep Panicker /* ARGSUSED */ 1033*6bbe0590SSundeep Panicker int 1034*6bbe0590SSundeep Panicker fru_get_packets(segment_hdl_t segment, packet_t *packet, int maxpackets, 1035*6bbe0590SSundeep Panicker door_cred_t *cred) 1036*6bbe0590SSundeep Panicker { 1037*6bbe0590SSundeep Panicker int count; 1038*6bbe0590SSundeep Panicker hash_obj_t *seg_hash_obj; 1039*6bbe0590SSundeep Panicker hash_obj_t *pkt_hash_obj; 1040*6bbe0590SSundeep Panicker 1041*6bbe0590SSundeep Panicker /* segment hash object */ 1042*6bbe0590SSundeep Panicker seg_hash_obj = lookup_handle_object(segment, SEGMENT_TYPE); 1043*6bbe0590SSundeep Panicker if (seg_hash_obj == NULL) { 1044*6bbe0590SSundeep Panicker return (-1); 1045*6bbe0590SSundeep Panicker } 1046*6bbe0590SSundeep Panicker 1047*6bbe0590SSundeep Panicker if (seg_hash_obj->u.seg_obj->num_of_packets != maxpackets) { 1048*6bbe0590SSundeep Panicker return (-1); 1049*6bbe0590SSundeep Panicker } 1050*6bbe0590SSundeep Panicker 1051*6bbe0590SSundeep Panicker pkt_hash_obj = seg_hash_obj->u.seg_obj->pkt_obj_list; 1052*6bbe0590SSundeep Panicker if (pkt_hash_obj == NULL) { 1053*6bbe0590SSundeep Panicker return (-1); 1054*6bbe0590SSundeep Panicker } 1055*6bbe0590SSundeep Panicker 1056*6bbe0590SSundeep Panicker for (count = 0; count < maxpackets; count++, packet++) { 1057*6bbe0590SSundeep Panicker packet->handle = pkt_hash_obj->obj_hdl; 1058*6bbe0590SSundeep Panicker packet->tag = 0; 1059*6bbe0590SSundeep Panicker (void) memcpy(&packet->tag, &pkt_hash_obj->u.pkt_obj->tag, 1060*6bbe0590SSundeep Panicker pkt_hash_obj->u.pkt_obj->tag_size); 1061*6bbe0590SSundeep Panicker pkt_hash_obj = pkt_hash_obj->u.pkt_obj->next; 1062*6bbe0590SSundeep Panicker } 1063*6bbe0590SSundeep Panicker 1064*6bbe0590SSundeep Panicker return (0); 1065*6bbe0590SSundeep Panicker } 1066*6bbe0590SSundeep Panicker 1067*6bbe0590SSundeep Panicker /* ARGSUSED */ 1068*6bbe0590SSundeep Panicker ssize_t 1069*6bbe0590SSundeep Panicker fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes, 1070*6bbe0590SSundeep Panicker door_cred_t *cred) 1071*6bbe0590SSundeep Panicker { 1072*6bbe0590SSundeep Panicker hash_obj_t *packet_hash_obj; 1073*6bbe0590SSundeep Panicker 1074*6bbe0590SSundeep Panicker /* packet hash object */ 1075*6bbe0590SSundeep Panicker packet_hash_obj = lookup_handle_object(packet, PACKET_TYPE); 1076*6bbe0590SSundeep Panicker if (packet_hash_obj == NULL) { 1077*6bbe0590SSundeep Panicker return (-1); 1078*6bbe0590SSundeep Panicker } 1079*6bbe0590SSundeep Panicker 1080*6bbe0590SSundeep Panicker /* verify payload length */ 1081*6bbe0590SSundeep Panicker if (nbytes != packet_hash_obj->u.pkt_obj->paylen) { 1082*6bbe0590SSundeep Panicker return (-1); 1083*6bbe0590SSundeep Panicker } 1084*6bbe0590SSundeep Panicker 1085*6bbe0590SSundeep Panicker (void) memcpy(buffer, packet_hash_obj->u.pkt_obj->payload, nbytes); 1086*6bbe0590SSundeep Panicker return (nbytes); 1087*6bbe0590SSundeep Panicker } 1088*6bbe0590SSundeep Panicker 1089*6bbe0590SSundeep Panicker 1090*6bbe0590SSundeep Panicker container_hdl_t 1091*6bbe0590SSundeep Panicker open_raw_data(raw_list_t *node) 1092*6bbe0590SSundeep Panicker { 1093*6bbe0590SSundeep Panicker char *cont_conf_file = NULL; 1094*6bbe0590SSundeep Panicker hash_obj_t *cont_hash_obj; 1095*6bbe0590SSundeep Panicker hash_obj_t *sec_hash_obj; 1096*6bbe0590SSundeep Panicker container_info_t cont_info; 1097*6bbe0590SSundeep Panicker int retval; 1098*6bbe0590SSundeep Panicker int count; 1099*6bbe0590SSundeep Panicker 1100*6bbe0590SSundeep Panicker cont_hash_obj = create_container_hash_object(); 1101*6bbe0590SSundeep Panicker if (cont_hash_obj == NULL) { 1102*6bbe0590SSundeep Panicker return (NULL); 1103*6bbe0590SSundeep Panicker } 1104*6bbe0590SSundeep Panicker 1105*6bbe0590SSundeep Panicker add_hashobject_to_hashtable(cont_hash_obj); 1106*6bbe0590SSundeep Panicker 1107*6bbe0590SSundeep Panicker (void) strncpy(cont_hash_obj->u.cont_obj->device_pathname, "unknown", 1108*6bbe0590SSundeep Panicker sizeof (cont_hash_obj->u.cont_obj->device_pathname)); 1109*6bbe0590SSundeep Panicker 1110*6bbe0590SSundeep Panicker cont_conf_file = getenv(FRU_CONT_CONF_ENV_VAR); 1111*6bbe0590SSundeep Panicker if (cont_conf_file == NULL) { 1112*6bbe0590SSundeep Panicker cont_conf_file = FRU_CONT_CONF_SPARC; 1113*6bbe0590SSundeep Panicker retval = get_container_info(cont_conf_file, node->cont_type, 1114*6bbe0590SSundeep Panicker &cont_info); 1115*6bbe0590SSundeep Panicker if (retval < 0) { 1116*6bbe0590SSundeep Panicker cont_conf_file = FRU_CONT_CONF_X86; 1117*6bbe0590SSundeep Panicker retval = get_container_info(cont_conf_file, 1118*6bbe0590SSundeep Panicker node->cont_type, &cont_info); 1119*6bbe0590SSundeep Panicker } 1120*6bbe0590SSundeep Panicker } else { 1121*6bbe0590SSundeep Panicker retval = get_container_info(cont_conf_file, node->cont_type, 1122*6bbe0590SSundeep Panicker &cont_info); 1123*6bbe0590SSundeep Panicker } 1124*6bbe0590SSundeep Panicker 1125*6bbe0590SSundeep Panicker if (retval < 0) { 1126*6bbe0590SSundeep Panicker return (NULL); 1127*6bbe0590SSundeep Panicker } 1128*6bbe0590SSundeep Panicker 1129*6bbe0590SSundeep Panicker cont_hash_obj->u.cont_obj->num_of_section = cont_info.num_sections; 1130*6bbe0590SSundeep Panicker cont_hash_obj->u.cont_obj->sec_obj_list = NULL; 1131*6bbe0590SSundeep Panicker 1132*6bbe0590SSundeep Panicker for (count = 0; count < cont_info.num_sections; count++) { 1133*6bbe0590SSundeep Panicker sec_hash_obj = create_section_hash_object(); 1134*6bbe0590SSundeep Panicker if (sec_hash_obj == NULL) { 1135*6bbe0590SSundeep Panicker return (NULL); 1136*6bbe0590SSundeep Panicker } 1137*6bbe0590SSundeep Panicker 1138*6bbe0590SSundeep Panicker add_hashobject_to_hashtable(sec_hash_obj); 1139*6bbe0590SSundeep Panicker 1140*6bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.offset = 1141*6bbe0590SSundeep Panicker cont_info.section_info[count].address; 1142*6bbe0590SSundeep Panicker 1143*6bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.protection = 1144*6bbe0590SSundeep Panicker cont_info.section_info[count].description.field.read_only; 1145*6bbe0590SSundeep Panicker 1146*6bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.length = 1147*6bbe0590SSundeep Panicker cont_info.section_info[count].size; 1148*6bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->section.version = 1149*6bbe0590SSundeep Panicker cont_info.header_ver; 1150*6bbe0590SSundeep Panicker 1151*6bbe0590SSundeep Panicker add_to_sec_object_list(cont_hash_obj, sec_hash_obj); 1152*6bbe0590SSundeep Panicker } 1153*6bbe0590SSundeep Panicker 1154*6bbe0590SSundeep Panicker return (cont_hash_obj->obj_hdl); 1155*6bbe0590SSundeep Panicker } 1156*6bbe0590SSundeep Panicker 1157*6bbe0590SSundeep Panicker 1158*6bbe0590SSundeep Panicker int 1159*6bbe0590SSundeep Panicker fru_close_container(container_hdl_t container) 1160*6bbe0590SSundeep Panicker { 1161*6bbe0590SSundeep Panicker hash_obj_t *hash_obj; 1162*6bbe0590SSundeep Panicker hash_obj_t *prev_hash; 1163*6bbe0590SSundeep Panicker hash_obj_t *sec_hash_obj; 1164*6bbe0590SSundeep Panicker handle_t obj_hdl; 1165*6bbe0590SSundeep Panicker 1166*6bbe0590SSundeep Panicker /* lookup for container hash object */ 1167*6bbe0590SSundeep Panicker hash_obj = lookup_handle_object(container, CONTAINER_TYPE); 1168*6bbe0590SSundeep Panicker if (hash_obj == NULL) { 1169*6bbe0590SSundeep Panicker return (0); 1170*6bbe0590SSundeep Panicker } 1171*6bbe0590SSundeep Panicker 1172*6bbe0590SSundeep Panicker /* points to section object list */ 1173*6bbe0590SSundeep Panicker sec_hash_obj = hash_obj->u.cont_obj->sec_obj_list; 1174*6bbe0590SSundeep Panicker 1175*6bbe0590SSundeep Panicker /* traverse section object list */ 1176*6bbe0590SSundeep Panicker while (sec_hash_obj != NULL) { 1177*6bbe0590SSundeep Panicker 1178*6bbe0590SSundeep Panicker /* traverse segment hash object in the section */ 1179*6bbe0590SSundeep Panicker while (sec_hash_obj->u.sec_obj->seg_obj_list != NULL) { 1180*6bbe0590SSundeep Panicker /* object handle of the segment hash object */ 1181*6bbe0590SSundeep Panicker obj_hdl = 1182*6bbe0590SSundeep Panicker sec_hash_obj->u.sec_obj->seg_obj_list->obj_hdl; 1183*6bbe0590SSundeep Panicker free_segment_hash(obj_hdl, sec_hash_obj); 1184*6bbe0590SSundeep Panicker } 1185*6bbe0590SSundeep Panicker 1186*6bbe0590SSundeep Panicker /* going to free section hash object, relink the hash object */ 1187*6bbe0590SSundeep Panicker if (sec_hash_obj->prev == NULL) { 1188*6bbe0590SSundeep Panicker hash_table[(sec_hash_obj->obj_hdl % TABLE_SIZE)] = 1189*6bbe0590SSundeep Panicker sec_hash_obj->next; 1190*6bbe0590SSundeep Panicker if (sec_hash_obj->next != NULL) { 1191*6bbe0590SSundeep Panicker sec_hash_obj->next->prev = NULL; 1192*6bbe0590SSundeep Panicker } 1193*6bbe0590SSundeep Panicker } else { 1194*6bbe0590SSundeep Panicker sec_hash_obj->prev->next = sec_hash_obj->next; 1195*6bbe0590SSundeep Panicker if (sec_hash_obj->next != NULL) { 1196*6bbe0590SSundeep Panicker sec_hash_obj->next->prev = sec_hash_obj->prev; 1197*6bbe0590SSundeep Panicker } 1198*6bbe0590SSundeep Panicker } 1199*6bbe0590SSundeep Panicker 1200*6bbe0590SSundeep Panicker free(sec_hash_obj->u.sec_obj); /* free section hash object */ 1201*6bbe0590SSundeep Panicker 1202*6bbe0590SSundeep Panicker prev_hash = sec_hash_obj; 1203*6bbe0590SSundeep Panicker 1204*6bbe0590SSundeep Panicker sec_hash_obj = sec_hash_obj->u.sec_obj->next; 1205*6bbe0590SSundeep Panicker 1206*6bbe0590SSundeep Panicker free(prev_hash); /* free section hash */ 1207*6bbe0590SSundeep Panicker } 1208*6bbe0590SSundeep Panicker 1209*6bbe0590SSundeep Panicker /* free container hash object */ 1210*6bbe0590SSundeep Panicker if (hash_obj->prev == NULL) { 1211*6bbe0590SSundeep Panicker hash_table[(hash_obj->obj_hdl % TABLE_SIZE)] = 1212*6bbe0590SSundeep Panicker hash_obj->next; 1213*6bbe0590SSundeep Panicker if (hash_obj->next != NULL) { 1214*6bbe0590SSundeep Panicker hash_obj->next->prev = NULL; 1215*6bbe0590SSundeep Panicker } 1216*6bbe0590SSundeep Panicker } else { 1217*6bbe0590SSundeep Panicker hash_obj->prev->next = hash_obj->next; 1218*6bbe0590SSundeep Panicker if (hash_obj->next != NULL) { 1219*6bbe0590SSundeep Panicker hash_obj->next->prev = hash_obj->prev; 1220*6bbe0590SSundeep Panicker } 1221*6bbe0590SSundeep Panicker } 1222*6bbe0590SSundeep Panicker 1223*6bbe0590SSundeep Panicker free(hash_obj->u.cont_obj); 1224*6bbe0590SSundeep Panicker free(hash_obj); 1225*6bbe0590SSundeep Panicker 1226*6bbe0590SSundeep Panicker return (0); 1227*6bbe0590SSundeep Panicker } 1228