1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * This file contains kernel property decode routines adopted from 31*0Sstevel@tonic-gate * sunddi.c and ddi_impl.c. The following changes have been applied. 32*0Sstevel@tonic-gate * 33*0Sstevel@tonic-gate * (1) Replace kmem_alloc by malloc. Remove negative indexing 34*0Sstevel@tonic-gate * (2) Decoding applies only to prom properties. 35*0Sstevel@tonic-gate * (3) For strings, the return value is a composite string, not a string array. 36*0Sstevel@tonic-gate * (4) impl_ddi_prop_int_from_prom() uses _LITTLE_ENDIAN from isa_defs.h 37*0Sstevel@tonic-gate * 38*0Sstevel@tonic-gate * XXX This file should be kept in sync with kernel property encoding. 39*0Sstevel@tonic-gate */ 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #include <stdlib.h> 42*0Sstevel@tonic-gate #include <strings.h> 43*0Sstevel@tonic-gate #include <synch.h> 44*0Sstevel@tonic-gate #include <ctype.h> 45*0Sstevel@tonic-gate #include <sys/types.h> 46*0Sstevel@tonic-gate #include <sys/dditypes.h> 47*0Sstevel@tonic-gate #include <sys/ddipropdefs.h> 48*0Sstevel@tonic-gate #include <sys/isa_defs.h> 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate #include "libdevinfo.h" 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate /* 53*0Sstevel@tonic-gate * Return an integer in native machine format from an OBP 1275 integer 54*0Sstevel@tonic-gate * representation, which is big-endian, with no particular alignment 55*0Sstevel@tonic-gate * guarantees. intp points to the OBP data, and n the number of bytes. 56*0Sstevel@tonic-gate * 57*0Sstevel@tonic-gate * Byte-swapping may be needed on some implementations. 58*0Sstevel@tonic-gate */ 59*0Sstevel@tonic-gate int 60*0Sstevel@tonic-gate impl_di_prop_int_from_prom(uchar_t *intp, int n) 61*0Sstevel@tonic-gate { 62*0Sstevel@tonic-gate int i = 0; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN) 65*0Sstevel@tonic-gate intp += n; 66*0Sstevel@tonic-gate while (n-- > 0) { 67*0Sstevel@tonic-gate i = (i << 8) | *(--intp); 68*0Sstevel@tonic-gate } 69*0Sstevel@tonic-gate #else 70*0Sstevel@tonic-gate while (n-- > 0) { 71*0Sstevel@tonic-gate i = (i << 8) | *intp++; 72*0Sstevel@tonic-gate } 73*0Sstevel@tonic-gate #endif /* defined(_LITTLE_ENDIAN) */ 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate return (i); 76*0Sstevel@tonic-gate } 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate /* 79*0Sstevel@tonic-gate * Reset the current location pointer in the property handle to the 80*0Sstevel@tonic-gate * beginning of the data. 81*0Sstevel@tonic-gate */ 82*0Sstevel@tonic-gate void 83*0Sstevel@tonic-gate di_prop_reset_pos(prop_handle_t *ph) 84*0Sstevel@tonic-gate { 85*0Sstevel@tonic-gate ph->ph_cur_pos = ph->ph_data; 86*0Sstevel@tonic-gate ph->ph_save_pos = ph->ph_data; 87*0Sstevel@tonic-gate } 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate /* 90*0Sstevel@tonic-gate * Restore the current location pointer in the property handle to the 91*0Sstevel@tonic-gate * saved position. 92*0Sstevel@tonic-gate */ 93*0Sstevel@tonic-gate void 94*0Sstevel@tonic-gate di_prop_save_pos(prop_handle_t *ph) 95*0Sstevel@tonic-gate { 96*0Sstevel@tonic-gate ph->ph_save_pos = ph->ph_cur_pos; 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate /* 100*0Sstevel@tonic-gate * Save the location that the current location poiner is pointing to.. 101*0Sstevel@tonic-gate */ 102*0Sstevel@tonic-gate void 103*0Sstevel@tonic-gate di_prop_restore_pos(prop_handle_t *ph) 104*0Sstevel@tonic-gate { 105*0Sstevel@tonic-gate ph->ph_cur_pos = ph->ph_save_pos; 106*0Sstevel@tonic-gate } 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate /* 109*0Sstevel@tonic-gate * Property encode/decode functions 110*0Sstevel@tonic-gate */ 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate /* 113*0Sstevel@tonic-gate * Decode an array of integers property 114*0Sstevel@tonic-gate */ 115*0Sstevel@tonic-gate static int 116*0Sstevel@tonic-gate di_prop_fm_decode_ints(prop_handle_t *ph, void *data, uint_t *nelements) 117*0Sstevel@tonic-gate { 118*0Sstevel@tonic-gate int i; 119*0Sstevel@tonic-gate int cnt = 0; 120*0Sstevel@tonic-gate int *tmp; 121*0Sstevel@tonic-gate int *intp; 122*0Sstevel@tonic-gate int n; 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate /* 125*0Sstevel@tonic-gate * Figure out how many array elements there are by going through the 126*0Sstevel@tonic-gate * data without decoding it first and counting. 127*0Sstevel@tonic-gate */ 128*0Sstevel@tonic-gate for (;;) { 129*0Sstevel@tonic-gate i = DDI_PROP_INT(ph, DDI_PROP_CMD_SKIP, NULL); 130*0Sstevel@tonic-gate if (i < 0) 131*0Sstevel@tonic-gate break; 132*0Sstevel@tonic-gate cnt++; 133*0Sstevel@tonic-gate } 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate /* 136*0Sstevel@tonic-gate * If there are no elements return an error 137*0Sstevel@tonic-gate */ 138*0Sstevel@tonic-gate if (cnt == 0) 139*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate /* 142*0Sstevel@tonic-gate * If we cannot skip through the data, we cannot decode it 143*0Sstevel@tonic-gate */ 144*0Sstevel@tonic-gate if (i == DDI_PROP_RESULT_ERROR) 145*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* 148*0Sstevel@tonic-gate * Reset the data pointer to the beginning of the encoded data 149*0Sstevel@tonic-gate */ 150*0Sstevel@tonic-gate di_prop_reset_pos(ph); 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate /* 153*0Sstevel@tonic-gate * Allocated memory to store the decoded value in. 154*0Sstevel@tonic-gate */ 155*0Sstevel@tonic-gate if ((intp = malloc(cnt * sizeof (int))) == NULL) { 156*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate /* 161*0Sstevel@tonic-gate * Decode each elemente and place it in the space we just allocated 162*0Sstevel@tonic-gate */ 163*0Sstevel@tonic-gate tmp = intp; 164*0Sstevel@tonic-gate for (n = 0; n < cnt; n++, tmp++) { 165*0Sstevel@tonic-gate i = DDI_PROP_INT(ph, DDI_PROP_CMD_DECODE, tmp); 166*0Sstevel@tonic-gate if (i < DDI_PROP_RESULT_OK) { 167*0Sstevel@tonic-gate /* 168*0Sstevel@tonic-gate * Free the space we just allocated 169*0Sstevel@tonic-gate * and return an error. 170*0Sstevel@tonic-gate */ 171*0Sstevel@tonic-gate free(intp); 172*0Sstevel@tonic-gate switch (i) { 173*0Sstevel@tonic-gate case DDI_PROP_RESULT_EOF: 174*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate case DDI_PROP_RESULT_ERROR: 177*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate *nelements = cnt; 183*0Sstevel@tonic-gate *(int **)data = intp; 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate return (DDI_PROP_SUCCESS); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate /* 189*0Sstevel@tonic-gate * Decode an array of strings. 190*0Sstevel@tonic-gate */ 191*0Sstevel@tonic-gate static int 192*0Sstevel@tonic-gate di_prop_fm_decode_strings(prop_handle_t *ph, void *data, uint_t *nelements) 193*0Sstevel@tonic-gate { 194*0Sstevel@tonic-gate int cnt = 0; 195*0Sstevel@tonic-gate char *strs; 196*0Sstevel@tonic-gate char *tmp; 197*0Sstevel@tonic-gate int size; 198*0Sstevel@tonic-gate int i; 199*0Sstevel@tonic-gate int n; 200*0Sstevel@tonic-gate int nbytes; 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate /* 203*0Sstevel@tonic-gate * Figure out how much memory we need for the sum total 204*0Sstevel@tonic-gate */ 205*0Sstevel@tonic-gate nbytes = 0; 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate for (;;) { 208*0Sstevel@tonic-gate /* 209*0Sstevel@tonic-gate * Get the decoded size of the current encoded string. 210*0Sstevel@tonic-gate */ 211*0Sstevel@tonic-gate size = DDI_PROP_STR(ph, DDI_PROP_CMD_GET_DSIZE, NULL); 212*0Sstevel@tonic-gate if (size < 0) 213*0Sstevel@tonic-gate break; 214*0Sstevel@tonic-gate 215*0Sstevel@tonic-gate cnt++; 216*0Sstevel@tonic-gate nbytes += size; 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate /* 220*0Sstevel@tonic-gate * If there are no elements return an error 221*0Sstevel@tonic-gate */ 222*0Sstevel@tonic-gate if (cnt == 0) 223*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate /* 226*0Sstevel@tonic-gate * If we cannot skip through the data, we cannot decode it 227*0Sstevel@tonic-gate */ 228*0Sstevel@tonic-gate if (size == DDI_PROP_RESULT_ERROR) 229*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate /* 232*0Sstevel@tonic-gate * Allocate memory in which to store the decoded strings. 233*0Sstevel@tonic-gate */ 234*0Sstevel@tonic-gate if ((strs = malloc(nbytes)) == NULL) { 235*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate /* 239*0Sstevel@tonic-gate * Finally, we can decode each string 240*0Sstevel@tonic-gate */ 241*0Sstevel@tonic-gate di_prop_reset_pos(ph); 242*0Sstevel@tonic-gate tmp = strs; 243*0Sstevel@tonic-gate for (n = 0; n < cnt; n++) { 244*0Sstevel@tonic-gate i = DDI_PROP_STR(ph, DDI_PROP_CMD_DECODE, tmp); 245*0Sstevel@tonic-gate if (i < DDI_PROP_RESULT_OK) { 246*0Sstevel@tonic-gate /* 247*0Sstevel@tonic-gate * Free the space we just allocated 248*0Sstevel@tonic-gate * and return an error 249*0Sstevel@tonic-gate */ 250*0Sstevel@tonic-gate free(strs); 251*0Sstevel@tonic-gate switch (i) { 252*0Sstevel@tonic-gate case DDI_PROP_RESULT_EOF: 253*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate case DDI_PROP_RESULT_ERROR: 256*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate tmp += strlen(tmp) + 1; 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate *(char **)data = strs; 263*0Sstevel@tonic-gate *nelements = cnt; 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate return (DDI_PROP_SUCCESS); 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate /* 269*0Sstevel@tonic-gate * Decode an array of bytes. 270*0Sstevel@tonic-gate */ 271*0Sstevel@tonic-gate static int 272*0Sstevel@tonic-gate di_prop_fm_decode_bytes(prop_handle_t *ph, void *data, uint_t *nelements) 273*0Sstevel@tonic-gate { 274*0Sstevel@tonic-gate uchar_t *tmp; 275*0Sstevel@tonic-gate int nbytes; 276*0Sstevel@tonic-gate int i; 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate /* 279*0Sstevel@tonic-gate * If there are no elements return an error 280*0Sstevel@tonic-gate */ 281*0Sstevel@tonic-gate if (ph->ph_size == 0) 282*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate /* 285*0Sstevel@tonic-gate * Get the size of the encoded array of bytes. 286*0Sstevel@tonic-gate */ 287*0Sstevel@tonic-gate nbytes = DDI_PROP_BYTES(ph, DDI_PROP_CMD_GET_DSIZE, 288*0Sstevel@tonic-gate data, ph->ph_size); 289*0Sstevel@tonic-gate if (nbytes < DDI_PROP_RESULT_OK) { 290*0Sstevel@tonic-gate switch (nbytes) { 291*0Sstevel@tonic-gate case DDI_PROP_RESULT_EOF: 292*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate case DDI_PROP_RESULT_ERROR: 295*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate /* 300*0Sstevel@tonic-gate * Allocated memory to store the decoded value in. 301*0Sstevel@tonic-gate */ 302*0Sstevel@tonic-gate if ((tmp = malloc(nbytes)) == NULL) { 303*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 304*0Sstevel@tonic-gate } 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate /* 307*0Sstevel@tonic-gate * Decode each element and place it in the space we just allocated 308*0Sstevel@tonic-gate */ 309*0Sstevel@tonic-gate i = DDI_PROP_BYTES(ph, DDI_PROP_CMD_DECODE, tmp, nbytes); 310*0Sstevel@tonic-gate if (i < DDI_PROP_RESULT_OK) { 311*0Sstevel@tonic-gate /* 312*0Sstevel@tonic-gate * Free the space we just allocated 313*0Sstevel@tonic-gate * and return an error 314*0Sstevel@tonic-gate */ 315*0Sstevel@tonic-gate free(tmp); 316*0Sstevel@tonic-gate switch (i) { 317*0Sstevel@tonic-gate case DDI_PROP_RESULT_EOF: 318*0Sstevel@tonic-gate return (DDI_PROP_END_OF_DATA); 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate case DDI_PROP_RESULT_ERROR: 321*0Sstevel@tonic-gate return (DDI_PROP_CANNOT_DECODE); 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate *(uchar_t **)data = tmp; 326*0Sstevel@tonic-gate *nelements = nbytes; 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate return (DDI_PROP_SUCCESS); 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate /* 332*0Sstevel@tonic-gate * OBP 1275 integer, string and byte operators. 333*0Sstevel@tonic-gate * 334*0Sstevel@tonic-gate * DDI_PROP_CMD_DECODE: 335*0Sstevel@tonic-gate * 336*0Sstevel@tonic-gate * DDI_PROP_RESULT_ERROR: cannot decode the data 337*0Sstevel@tonic-gate * DDI_PROP_RESULT_EOF: end of data 338*0Sstevel@tonic-gate * DDI_PROP_OK: data was decoded 339*0Sstevel@tonic-gate * 340*0Sstevel@tonic-gate * DDI_PROP_CMD_ENCODE: 341*0Sstevel@tonic-gate * 342*0Sstevel@tonic-gate * DDI_PROP_RESULT_ERROR: cannot encode the data 343*0Sstevel@tonic-gate * DDI_PROP_RESULT_EOF: end of data 344*0Sstevel@tonic-gate * DDI_PROP_OK: data was encoded 345*0Sstevel@tonic-gate * 346*0Sstevel@tonic-gate * DDI_PROP_CMD_SKIP: 347*0Sstevel@tonic-gate * 348*0Sstevel@tonic-gate * DDI_PROP_RESULT_ERROR: cannot skip the data 349*0Sstevel@tonic-gate * DDI_PROP_RESULT_EOF: end of data 350*0Sstevel@tonic-gate * DDI_PROP_OK: data was skipped 351*0Sstevel@tonic-gate * 352*0Sstevel@tonic-gate * DDI_PROP_CMD_GET_ESIZE: 353*0Sstevel@tonic-gate * 354*0Sstevel@tonic-gate * DDI_PROP_RESULT_ERROR: cannot get encoded size 355*0Sstevel@tonic-gate * DDI_PROP_RESULT_EOF: end of data 356*0Sstevel@tonic-gate * > 0: the encoded size 357*0Sstevel@tonic-gate * 358*0Sstevel@tonic-gate * DDI_PROP_CMD_GET_DSIZE: 359*0Sstevel@tonic-gate * 360*0Sstevel@tonic-gate * DDI_PROP_RESULT_ERROR: cannot get decoded size 361*0Sstevel@tonic-gate * DDI_PROP_RESULT_EOF: end of data 362*0Sstevel@tonic-gate * > 0: the decoded size 363*0Sstevel@tonic-gate */ 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate /* 366*0Sstevel@tonic-gate * OBP 1275 integer operator 367*0Sstevel@tonic-gate * 368*0Sstevel@tonic-gate * OBP properties are a byte stream of data, so integers may not be 369*0Sstevel@tonic-gate * properly aligned. Therefore we need to copy them one byte at a time. 370*0Sstevel@tonic-gate */ 371*0Sstevel@tonic-gate int 372*0Sstevel@tonic-gate di_prop_1275_int(prop_handle_t *ph, uint_t cmd, int *data) 373*0Sstevel@tonic-gate { 374*0Sstevel@tonic-gate int i; 375*0Sstevel@tonic-gate 376*0Sstevel@tonic-gate switch (cmd) { 377*0Sstevel@tonic-gate case DDI_PROP_CMD_DECODE: 378*0Sstevel@tonic-gate /* 379*0Sstevel@tonic-gate * Check that there is encoded data 380*0Sstevel@tonic-gate */ 381*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0) 382*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 383*0Sstevel@tonic-gate if (ph->ph_flags & PH_FROM_PROM) { 384*0Sstevel@tonic-gate i = ph->ph_size < PROP_1275_INT_SIZE ? 385*0Sstevel@tonic-gate ph->ph_size : PROP_1275_INT_SIZE; 386*0Sstevel@tonic-gate if ((int *)ph->ph_cur_pos > ((int *)ph->ph_data + 387*0Sstevel@tonic-gate ph->ph_size - i)) 388*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 389*0Sstevel@tonic-gate } else if (ph->ph_size < sizeof (int) || 390*0Sstevel@tonic-gate ((int *)ph->ph_cur_pos > ((int *)ph->ph_data + 391*0Sstevel@tonic-gate ph->ph_size - sizeof (int)))) { 392*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 393*0Sstevel@tonic-gate } 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate /* 396*0Sstevel@tonic-gate * Copy the integer, using the implementation-specific 397*0Sstevel@tonic-gate * copy function if the property is coming from the PROM. 398*0Sstevel@tonic-gate */ 399*0Sstevel@tonic-gate if (ph->ph_flags & PH_FROM_PROM) { 400*0Sstevel@tonic-gate *data = impl_di_prop_int_from_prom( 401*0Sstevel@tonic-gate (uchar_t *)ph->ph_cur_pos, 402*0Sstevel@tonic-gate (ph->ph_size < PROP_1275_INT_SIZE) ? 403*0Sstevel@tonic-gate ph->ph_size : PROP_1275_INT_SIZE); 404*0Sstevel@tonic-gate } else { 405*0Sstevel@tonic-gate bcopy(ph->ph_cur_pos, (caddr_t)data, sizeof (int)); 406*0Sstevel@tonic-gate } 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate /* 409*0Sstevel@tonic-gate * Move the current location to the start of the next 410*0Sstevel@tonic-gate * bit of undecoded data. 411*0Sstevel@tonic-gate */ 412*0Sstevel@tonic-gate ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + PROP_1275_INT_SIZE; 413*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate case DDI_PROP_CMD_ENCODE: 416*0Sstevel@tonic-gate /* 417*0Sstevel@tonic-gate * Check that there is room to encoded the data 418*0Sstevel@tonic-gate */ 419*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 420*0Sstevel@tonic-gate ph->ph_size < PROP_1275_INT_SIZE || 421*0Sstevel@tonic-gate ((int *)ph->ph_cur_pos > ((int *)ph->ph_data + 422*0Sstevel@tonic-gate ph->ph_size - sizeof (int)))) 423*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate /* 426*0Sstevel@tonic-gate * Encode the integer into the byte stream one byte at a 427*0Sstevel@tonic-gate * time. 428*0Sstevel@tonic-gate */ 429*0Sstevel@tonic-gate bcopy((caddr_t)data, ph->ph_cur_pos, sizeof (int)); 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate /* 432*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 433*0Sstevel@tonic-gate * space where we can store encoded data. 434*0Sstevel@tonic-gate */ 435*0Sstevel@tonic-gate ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + PROP_1275_INT_SIZE; 436*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate case DDI_PROP_CMD_SKIP: 439*0Sstevel@tonic-gate /* 440*0Sstevel@tonic-gate * Check that there is encoded data 441*0Sstevel@tonic-gate */ 442*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 443*0Sstevel@tonic-gate ph->ph_size < PROP_1275_INT_SIZE) 444*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate if ((caddr_t)ph->ph_cur_pos == 448*0Sstevel@tonic-gate (caddr_t)ph->ph_data + ph->ph_size) { 449*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 450*0Sstevel@tonic-gate } else if ((caddr_t)ph->ph_cur_pos > 451*0Sstevel@tonic-gate (caddr_t)ph->ph_data + ph->ph_size) { 452*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gate /* 456*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 457*0Sstevel@tonic-gate * undecoded data. 458*0Sstevel@tonic-gate */ 459*0Sstevel@tonic-gate ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + PROP_1275_INT_SIZE; 460*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_ESIZE: 463*0Sstevel@tonic-gate /* 464*0Sstevel@tonic-gate * Return the size of an encoded integer on OBP 465*0Sstevel@tonic-gate */ 466*0Sstevel@tonic-gate return (PROP_1275_INT_SIZE); 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_DSIZE: 469*0Sstevel@tonic-gate /* 470*0Sstevel@tonic-gate * Return the size of a decoded integer on the system. 471*0Sstevel@tonic-gate */ 472*0Sstevel@tonic-gate return (sizeof (int)); 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate /*NOTREACHED*/ 476*0Sstevel@tonic-gate return (0); /* keep gcc happy */ 477*0Sstevel@tonic-gate } 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate /* 480*0Sstevel@tonic-gate * 64 bit integer operator 481*0Sstevel@tonic-gate * 482*0Sstevel@tonic-gate * This is an extension, defined by Sun, to the 1275 integer 483*0Sstevel@tonic-gate * operator. This routine handles the encoding/decoding of 484*0Sstevel@tonic-gate * 64 bit integer properties. 485*0Sstevel@tonic-gate */ 486*0Sstevel@tonic-gate int 487*0Sstevel@tonic-gate di_prop_int64_op(prop_handle_t *ph, uint_t cmd, int64_t *data) 488*0Sstevel@tonic-gate { 489*0Sstevel@tonic-gate switch (cmd) { 490*0Sstevel@tonic-gate case DDI_PROP_CMD_DECODE: 491*0Sstevel@tonic-gate /* 492*0Sstevel@tonic-gate * Check that there is encoded data 493*0Sstevel@tonic-gate */ 494*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0) 495*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 496*0Sstevel@tonic-gate if (ph->ph_flags & PH_FROM_PROM) { 497*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 498*0Sstevel@tonic-gate } else if (ph->ph_size < sizeof (int64_t) || 499*0Sstevel@tonic-gate ((int64_t *)ph->ph_cur_pos > ((int64_t *)ph->ph_data + 500*0Sstevel@tonic-gate ph->ph_size - sizeof (int64_t)))) { 501*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 502*0Sstevel@tonic-gate } 503*0Sstevel@tonic-gate 504*0Sstevel@tonic-gate /* 505*0Sstevel@tonic-gate * Copy the integer, using the implementation-specific 506*0Sstevel@tonic-gate * copy function if the property is coming from the PROM. 507*0Sstevel@tonic-gate */ 508*0Sstevel@tonic-gate bcopy(ph->ph_cur_pos, (caddr_t)data, sizeof (int64_t)); 509*0Sstevel@tonic-gate 510*0Sstevel@tonic-gate /* 511*0Sstevel@tonic-gate * Move the current location to the start of the next 512*0Sstevel@tonic-gate * bit of undecoded data. 513*0Sstevel@tonic-gate */ 514*0Sstevel@tonic-gate ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + 515*0Sstevel@tonic-gate sizeof (int64_t); 516*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate case DDI_PROP_CMD_ENCODE: 519*0Sstevel@tonic-gate /* 520*0Sstevel@tonic-gate * Check that there is room to encoded the data 521*0Sstevel@tonic-gate */ 522*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 523*0Sstevel@tonic-gate ph->ph_size < sizeof (int64_t) || 524*0Sstevel@tonic-gate ((int64_t *)ph->ph_cur_pos > ((int64_t *)ph->ph_data + 525*0Sstevel@tonic-gate ph->ph_size - sizeof (int64_t)))) 526*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 527*0Sstevel@tonic-gate 528*0Sstevel@tonic-gate /* 529*0Sstevel@tonic-gate * Encode the integer into the byte stream one byte at a 530*0Sstevel@tonic-gate * time. 531*0Sstevel@tonic-gate */ 532*0Sstevel@tonic-gate bcopy((caddr_t)data, ph->ph_cur_pos, sizeof (int64_t)); 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate /* 535*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 536*0Sstevel@tonic-gate * space where we can store encoded data. 537*0Sstevel@tonic-gate */ 538*0Sstevel@tonic-gate ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + 539*0Sstevel@tonic-gate sizeof (int64_t); 540*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 541*0Sstevel@tonic-gate 542*0Sstevel@tonic-gate case DDI_PROP_CMD_SKIP: 543*0Sstevel@tonic-gate /* 544*0Sstevel@tonic-gate * Check that there is encoded data 545*0Sstevel@tonic-gate */ 546*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 547*0Sstevel@tonic-gate ph->ph_size < sizeof (int64_t)) 548*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gate if ((caddr_t)ph->ph_cur_pos == 552*0Sstevel@tonic-gate (caddr_t)ph->ph_data + ph->ph_size) { 553*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 554*0Sstevel@tonic-gate } else if ((caddr_t)ph->ph_cur_pos > 555*0Sstevel@tonic-gate (caddr_t)ph->ph_data + ph->ph_size) { 556*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 557*0Sstevel@tonic-gate } 558*0Sstevel@tonic-gate 559*0Sstevel@tonic-gate /* 560*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 561*0Sstevel@tonic-gate * undecoded data. 562*0Sstevel@tonic-gate */ 563*0Sstevel@tonic-gate ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + 564*0Sstevel@tonic-gate sizeof (int64_t); 565*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_ESIZE: 568*0Sstevel@tonic-gate /* 569*0Sstevel@tonic-gate * Return the size of an encoded integer on OBP 570*0Sstevel@tonic-gate */ 571*0Sstevel@tonic-gate return (sizeof (int64_t)); 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_DSIZE: 574*0Sstevel@tonic-gate /* 575*0Sstevel@tonic-gate * Return the size of a decoded integer on the system. 576*0Sstevel@tonic-gate */ 577*0Sstevel@tonic-gate return (sizeof (int64_t)); 578*0Sstevel@tonic-gate } 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate /*NOTREACHED*/ 581*0Sstevel@tonic-gate return (0); /* keep gcc happy */ 582*0Sstevel@tonic-gate } 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate /* 585*0Sstevel@tonic-gate * OBP 1275 string operator. 586*0Sstevel@tonic-gate * 587*0Sstevel@tonic-gate * OBP strings are NULL terminated. 588*0Sstevel@tonic-gate */ 589*0Sstevel@tonic-gate int 590*0Sstevel@tonic-gate di_prop_1275_string(prop_handle_t *ph, uint_t cmd, char *data) 591*0Sstevel@tonic-gate { 592*0Sstevel@tonic-gate int n; 593*0Sstevel@tonic-gate char *p; 594*0Sstevel@tonic-gate char *end; 595*0Sstevel@tonic-gate 596*0Sstevel@tonic-gate switch (cmd) { 597*0Sstevel@tonic-gate case DDI_PROP_CMD_DECODE: 598*0Sstevel@tonic-gate /* 599*0Sstevel@tonic-gate * Check that there is encoded data 600*0Sstevel@tonic-gate */ 601*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0) { 602*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 603*0Sstevel@tonic-gate } 604*0Sstevel@tonic-gate 605*0Sstevel@tonic-gate n = strlen((char *)ph->ph_cur_pos) + 1; 606*0Sstevel@tonic-gate if ((char *)ph->ph_cur_pos > ((char *)ph->ph_data + 607*0Sstevel@tonic-gate ph->ph_size - n)) { 608*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 609*0Sstevel@tonic-gate } 610*0Sstevel@tonic-gate 611*0Sstevel@tonic-gate /* 612*0Sstevel@tonic-gate * Copy the NULL terminated string 613*0Sstevel@tonic-gate */ 614*0Sstevel@tonic-gate bcopy((char *)ph->ph_cur_pos, data, n); 615*0Sstevel@tonic-gate 616*0Sstevel@tonic-gate /* 617*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 618*0Sstevel@tonic-gate * undecoded data. 619*0Sstevel@tonic-gate */ 620*0Sstevel@tonic-gate ph->ph_cur_pos = (char *)ph->ph_cur_pos + n; 621*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 622*0Sstevel@tonic-gate 623*0Sstevel@tonic-gate case DDI_PROP_CMD_ENCODE: 624*0Sstevel@tonic-gate /* 625*0Sstevel@tonic-gate * Check that there is room to encoded the data 626*0Sstevel@tonic-gate */ 627*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0) { 628*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 629*0Sstevel@tonic-gate } 630*0Sstevel@tonic-gate 631*0Sstevel@tonic-gate n = strlen(data) + 1; 632*0Sstevel@tonic-gate if ((char *)ph->ph_cur_pos > ((char *)ph->ph_data + 633*0Sstevel@tonic-gate ph->ph_size - n)) { 634*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 635*0Sstevel@tonic-gate } 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate /* 638*0Sstevel@tonic-gate * Copy the NULL terminated string 639*0Sstevel@tonic-gate */ 640*0Sstevel@tonic-gate bcopy(data, (char *)ph->ph_cur_pos, n); 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate /* 643*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 644*0Sstevel@tonic-gate * space where we can store encoded data. 645*0Sstevel@tonic-gate */ 646*0Sstevel@tonic-gate ph->ph_cur_pos = (char *)ph->ph_cur_pos + n; 647*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 648*0Sstevel@tonic-gate 649*0Sstevel@tonic-gate case DDI_PROP_CMD_SKIP: 650*0Sstevel@tonic-gate /* 651*0Sstevel@tonic-gate * Check that there is encoded data 652*0Sstevel@tonic-gate */ 653*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0) { 654*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 655*0Sstevel@tonic-gate } 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gate /* 658*0Sstevel@tonic-gate * Return the string length plus one for the NULL 659*0Sstevel@tonic-gate * We know the size of the property, we need to 660*0Sstevel@tonic-gate * ensure that the string is properly formatted, 661*0Sstevel@tonic-gate * since we may be looking up random OBP data. 662*0Sstevel@tonic-gate */ 663*0Sstevel@tonic-gate p = (char *)ph->ph_cur_pos; 664*0Sstevel@tonic-gate end = (char *)ph->ph_data + ph->ph_size; 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate if (p == end) { 667*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 668*0Sstevel@tonic-gate } 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gate /* 671*0Sstevel@tonic-gate * Make sure each char is printable 672*0Sstevel@tonic-gate */ 673*0Sstevel@tonic-gate for (n = 0; p < end && isascii(*p) && !iscntrl(*p); n++, p++) 674*0Sstevel@tonic-gate ; 675*0Sstevel@tonic-gate 676*0Sstevel@tonic-gate /* Check termination and non-zero length */ 677*0Sstevel@tonic-gate if ((*p == 0) && (n != 0)) { 678*0Sstevel@tonic-gate ph->ph_cur_pos = p + 1; 679*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 680*0Sstevel@tonic-gate } 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_ESIZE: 685*0Sstevel@tonic-gate /* 686*0Sstevel@tonic-gate * Return the size of the encoded string on OBP. 687*0Sstevel@tonic-gate */ 688*0Sstevel@tonic-gate return (strlen(data) + 1); 689*0Sstevel@tonic-gate 690*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_DSIZE: 691*0Sstevel@tonic-gate /* 692*0Sstevel@tonic-gate * Return the string length plus one for the NULL 693*0Sstevel@tonic-gate * We know the size of the property, we need to 694*0Sstevel@tonic-gate * ensure that the string is properly formatted, 695*0Sstevel@tonic-gate * since we may be looking up random OBP data. 696*0Sstevel@tonic-gate */ 697*0Sstevel@tonic-gate p = (char *)ph->ph_cur_pos; 698*0Sstevel@tonic-gate end = (char *)ph->ph_data + ph->ph_size; 699*0Sstevel@tonic-gate for (n = 0; p < end; n++) { 700*0Sstevel@tonic-gate if (*p++ == '\0') { 701*0Sstevel@tonic-gate ph->ph_cur_pos = p; 702*0Sstevel@tonic-gate return (n+1); 703*0Sstevel@tonic-gate } 704*0Sstevel@tonic-gate } 705*0Sstevel@tonic-gate 706*0Sstevel@tonic-gate /* 707*0Sstevel@tonic-gate * Add check here to separate EOF and ERROR. 708*0Sstevel@tonic-gate */ 709*0Sstevel@tonic-gate if (p == end) 710*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 713*0Sstevel@tonic-gate 714*0Sstevel@tonic-gate } 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate /*NOTREACHED*/ 717*0Sstevel@tonic-gate return (0); /* keep gcc happy */ 718*0Sstevel@tonic-gate } 719*0Sstevel@tonic-gate 720*0Sstevel@tonic-gate /* 721*0Sstevel@tonic-gate * OBP 1275 byte operator 722*0Sstevel@tonic-gate * 723*0Sstevel@tonic-gate * Caller must specify the number of bytes to get. OBP encodes bytes 724*0Sstevel@tonic-gate * as a byte so there is a 1-to-1 translation. 725*0Sstevel@tonic-gate */ 726*0Sstevel@tonic-gate int 727*0Sstevel@tonic-gate di_prop_1275_bytes(prop_handle_t *ph, uint_t cmd, uchar_t *data, 728*0Sstevel@tonic-gate uint_t nelements) 729*0Sstevel@tonic-gate { 730*0Sstevel@tonic-gate switch (cmd) { 731*0Sstevel@tonic-gate case DDI_PROP_CMD_DECODE: 732*0Sstevel@tonic-gate /* 733*0Sstevel@tonic-gate * Check that there is encoded data 734*0Sstevel@tonic-gate */ 735*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 736*0Sstevel@tonic-gate ph->ph_size < nelements || 737*0Sstevel@tonic-gate ((char *)ph->ph_cur_pos > ((char *)ph->ph_data + 738*0Sstevel@tonic-gate ph->ph_size - nelements))) 739*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate /* 742*0Sstevel@tonic-gate * Copy out the bytes 743*0Sstevel@tonic-gate */ 744*0Sstevel@tonic-gate bcopy((char *)ph->ph_cur_pos, (char *)data, nelements); 745*0Sstevel@tonic-gate 746*0Sstevel@tonic-gate /* 747*0Sstevel@tonic-gate * Move the current location 748*0Sstevel@tonic-gate */ 749*0Sstevel@tonic-gate ph->ph_cur_pos = (char *)ph->ph_cur_pos + nelements; 750*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gate case DDI_PROP_CMD_ENCODE: 753*0Sstevel@tonic-gate /* 754*0Sstevel@tonic-gate * Check that there is room to encode the data 755*0Sstevel@tonic-gate */ 756*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 757*0Sstevel@tonic-gate ph->ph_size < nelements || 758*0Sstevel@tonic-gate ((char *)ph->ph_cur_pos > ((char *)ph->ph_data + 759*0Sstevel@tonic-gate ph->ph_size - nelements))) 760*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate /* 763*0Sstevel@tonic-gate * Copy in the bytes 764*0Sstevel@tonic-gate */ 765*0Sstevel@tonic-gate bcopy((char *)data, (char *)ph->ph_cur_pos, nelements); 766*0Sstevel@tonic-gate 767*0Sstevel@tonic-gate /* 768*0Sstevel@tonic-gate * Move the current location to the start of the next bit of 769*0Sstevel@tonic-gate * space where we can store encoded data. 770*0Sstevel@tonic-gate */ 771*0Sstevel@tonic-gate ph->ph_cur_pos = (char *)ph->ph_cur_pos + nelements; 772*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 773*0Sstevel@tonic-gate 774*0Sstevel@tonic-gate case DDI_PROP_CMD_SKIP: 775*0Sstevel@tonic-gate /* 776*0Sstevel@tonic-gate * Check that there is encoded data 777*0Sstevel@tonic-gate */ 778*0Sstevel@tonic-gate if (ph->ph_cur_pos == NULL || ph->ph_size == 0 || 779*0Sstevel@tonic-gate ph->ph_size < nelements) 780*0Sstevel@tonic-gate return (DDI_PROP_RESULT_ERROR); 781*0Sstevel@tonic-gate 782*0Sstevel@tonic-gate if ((char *)ph->ph_cur_pos > ((char *)ph->ph_data + 783*0Sstevel@tonic-gate ph->ph_size - nelements)) 784*0Sstevel@tonic-gate return (DDI_PROP_RESULT_EOF); 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate /* 787*0Sstevel@tonic-gate * Move the current location 788*0Sstevel@tonic-gate */ 789*0Sstevel@tonic-gate ph->ph_cur_pos = (char *)ph->ph_cur_pos + nelements; 790*0Sstevel@tonic-gate return (DDI_PROP_RESULT_OK); 791*0Sstevel@tonic-gate 792*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_ESIZE: 793*0Sstevel@tonic-gate /* 794*0Sstevel@tonic-gate * The size in bytes of the encoded size is the 795*0Sstevel@tonic-gate * same as the decoded size provided by the caller. 796*0Sstevel@tonic-gate */ 797*0Sstevel@tonic-gate return (nelements); 798*0Sstevel@tonic-gate 799*0Sstevel@tonic-gate case DDI_PROP_CMD_GET_DSIZE: 800*0Sstevel@tonic-gate /* 801*0Sstevel@tonic-gate * Just return the number of bytes specified by the caller. 802*0Sstevel@tonic-gate */ 803*0Sstevel@tonic-gate return (nelements); 804*0Sstevel@tonic-gate 805*0Sstevel@tonic-gate } 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate /*NOTREACHED*/ 808*0Sstevel@tonic-gate return (0); /* keep gcc happy */ 809*0Sstevel@tonic-gate } 810*0Sstevel@tonic-gate 811*0Sstevel@tonic-gate /* 812*0Sstevel@tonic-gate * Used for properties that come from the OBP, hardware configuration files, 813*0Sstevel@tonic-gate * or that are created by calls to ddi_prop_update(9F). 814*0Sstevel@tonic-gate */ 815*0Sstevel@tonic-gate static struct prop_handle_ops prop_1275_ops = { 816*0Sstevel@tonic-gate di_prop_1275_int, 817*0Sstevel@tonic-gate di_prop_1275_string, 818*0Sstevel@tonic-gate di_prop_1275_bytes, 819*0Sstevel@tonic-gate di_prop_int64_op 820*0Sstevel@tonic-gate }; 821*0Sstevel@tonic-gate 822*0Sstevel@tonic-gate /* 823*0Sstevel@tonic-gate * Now the real thing: 824*0Sstevel@tonic-gate * Extract type-specific values of an property 825*0Sstevel@tonic-gate */ 826*0Sstevel@tonic-gate int 827*0Sstevel@tonic-gate di_prop_decode_common(void *data, int size, int prop_type, int prom) 828*0Sstevel@tonic-gate { 829*0Sstevel@tonic-gate int n; 830*0Sstevel@tonic-gate int nelements; 831*0Sstevel@tonic-gate char *cp, *end; 832*0Sstevel@tonic-gate prop_handle_t ph; 833*0Sstevel@tonic-gate int (*prop_decoder)(prop_handle_t *, void *, uint_t *); 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate /* 836*0Sstevel@tonic-gate * If the encoded data came from software, no decoding needed 837*0Sstevel@tonic-gate */ 838*0Sstevel@tonic-gate if (!prom) { 839*0Sstevel@tonic-gate switch (prop_type) { 840*0Sstevel@tonic-gate case DI_PROP_TYPE_INT: 841*0Sstevel@tonic-gate if (size % sizeof (int)) 842*0Sstevel@tonic-gate nelements = -1; 843*0Sstevel@tonic-gate else 844*0Sstevel@tonic-gate nelements = size / sizeof (int); 845*0Sstevel@tonic-gate break; 846*0Sstevel@tonic-gate 847*0Sstevel@tonic-gate case DI_PROP_TYPE_INT64: 848*0Sstevel@tonic-gate if (size % sizeof (int64_t)) 849*0Sstevel@tonic-gate nelements = -1; 850*0Sstevel@tonic-gate else 851*0Sstevel@tonic-gate nelements = size / sizeof (int64_t); 852*0Sstevel@tonic-gate break; 853*0Sstevel@tonic-gate 854*0Sstevel@tonic-gate case DI_PROP_TYPE_STRING: 855*0Sstevel@tonic-gate nelements = 0; 856*0Sstevel@tonic-gate cp = *(char **)data; 857*0Sstevel@tonic-gate end = cp + size; 858*0Sstevel@tonic-gate /* 859*0Sstevel@tonic-gate * Don't trust the data passed in by the caller. 860*0Sstevel@tonic-gate * Check every char to make sure it is indeed a 861*0Sstevel@tonic-gate * string property. 862*0Sstevel@tonic-gate */ 863*0Sstevel@tonic-gate while (cp < end) { 864*0Sstevel@tonic-gate /* skip to next non-printable char */ 865*0Sstevel@tonic-gate for (n = 0; cp < end && 866*0Sstevel@tonic-gate isascii(*cp) && !iscntrl(*cp); n++, cp++) 867*0Sstevel@tonic-gate ; 868*0Sstevel@tonic-gate 869*0Sstevel@tonic-gate /* 870*0Sstevel@tonic-gate * Fail if reached end (i.e. last char != 0), 871*0Sstevel@tonic-gate * or has a non-printable char. A zero length 872*0Sstevel@tonic-gate * string is acceptable. 873*0Sstevel@tonic-gate */ 874*0Sstevel@tonic-gate if (cp == end || *cp != 0) { 875*0Sstevel@tonic-gate nelements = -1; 876*0Sstevel@tonic-gate break; 877*0Sstevel@tonic-gate } 878*0Sstevel@tonic-gate /* 879*0Sstevel@tonic-gate * Increment # strings and keep going 880*0Sstevel@tonic-gate */ 881*0Sstevel@tonic-gate nelements++; 882*0Sstevel@tonic-gate cp++; 883*0Sstevel@tonic-gate } 884*0Sstevel@tonic-gate 885*0Sstevel@tonic-gate break; 886*0Sstevel@tonic-gate 887*0Sstevel@tonic-gate case DI_PROP_TYPE_BYTE: 888*0Sstevel@tonic-gate nelements = size; 889*0Sstevel@tonic-gate } 890*0Sstevel@tonic-gate 891*0Sstevel@tonic-gate return (nelements); 892*0Sstevel@tonic-gate } 893*0Sstevel@tonic-gate 894*0Sstevel@tonic-gate /* 895*0Sstevel@tonic-gate * Get the encoded data 896*0Sstevel@tonic-gate */ 897*0Sstevel@tonic-gate bzero((caddr_t)&ph, sizeof (prop_handle_t)); 898*0Sstevel@tonic-gate ph.ph_data = *(uchar_t **)data; 899*0Sstevel@tonic-gate ph.ph_size = size; 900*0Sstevel@tonic-gate 901*0Sstevel@tonic-gate /* 902*0Sstevel@tonic-gate * The data came from prom, use the 1275 OBP decode/encode routines. 903*0Sstevel@tonic-gate */ 904*0Sstevel@tonic-gate ph.ph_cur_pos = ph.ph_data; 905*0Sstevel@tonic-gate ph.ph_save_pos = ph.ph_data; 906*0Sstevel@tonic-gate ph.ph_ops = &prop_1275_ops; 907*0Sstevel@tonic-gate ph.ph_flags = PH_FROM_PROM; 908*0Sstevel@tonic-gate 909*0Sstevel@tonic-gate switch (prop_type) { 910*0Sstevel@tonic-gate case DI_PROP_TYPE_INT: 911*0Sstevel@tonic-gate prop_decoder = di_prop_fm_decode_ints; 912*0Sstevel@tonic-gate break; 913*0Sstevel@tonic-gate case DI_PROP_TYPE_STRING: 914*0Sstevel@tonic-gate prop_decoder = di_prop_fm_decode_strings; 915*0Sstevel@tonic-gate break; 916*0Sstevel@tonic-gate case DI_PROP_TYPE_BYTE: 917*0Sstevel@tonic-gate default: 918*0Sstevel@tonic-gate prop_decoder = di_prop_fm_decode_bytes; 919*0Sstevel@tonic-gate break; 920*0Sstevel@tonic-gate } 921*0Sstevel@tonic-gate 922*0Sstevel@tonic-gate if ((*prop_decoder)(&ph, data, (uint_t *)&nelements) 923*0Sstevel@tonic-gate != DDI_PROP_SUCCESS) 924*0Sstevel@tonic-gate return (-1); 925*0Sstevel@tonic-gate 926*0Sstevel@tonic-gate /* 927*0Sstevel@tonic-gate * Free the encoded data 928*0Sstevel@tonic-gate */ 929*0Sstevel@tonic-gate if (size != 0) 930*0Sstevel@tonic-gate free(ph.ph_data); 931*0Sstevel@tonic-gate 932*0Sstevel@tonic-gate return (nelements); 933*0Sstevel@tonic-gate } 934*0Sstevel@tonic-gate 935*0Sstevel@tonic-gate /* end of devinfo_prop_decode.c */ 936