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