1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/promif.h> 29 #include <sys/promimpl.h> 30 31 char * 32 prom_path_gettoken(register char *from, register char *to) 33 { 34 while (*from) { 35 switch (*from) { 36 case '/': 37 case '@': 38 case ':': 39 case ',': 40 *to = '\0'; 41 return (from); 42 default: 43 *to++ = *from++; 44 } 45 } 46 *to = '\0'; 47 return (from); 48 } 49 50 /* 51 * Given an OBP pathname, do the best we can to fully expand 52 * the OBP pathname, in place in the callers buffer. 53 * 54 * If we have to complete the addrspec of any component, we can 55 * only handle devices that have a maximum of NREGSPECS "reg" specs. 56 * We cannot allocate memory inside this function. 57 */ 58 void 59 prom_pathname(char *pathname) 60 { 61 char tmp[OBP_MAXPATHLEN]; 62 char *from = tmp; 63 char *to = pathname; 64 char *p; 65 cell_t ci[7]; 66 #ifdef PROM_32BIT_ADDRS 67 char *opathname = NULL; 68 #endif /* PROM_32BIT_ADDRS */ 69 70 if ((to == (char *)0) || (*to == (char)0)) 71 return; 72 73 #ifdef PROM_32BIT_ADDRS 74 if ((uintptr_t)pathname > (uint32_t)-1) { 75 opathname = pathname; 76 pathname = promplat_alloc(OBP_MAXPATHLEN); 77 if (pathname == NULL) { 78 return; 79 } 80 (void) prom_strcpy(pathname, opathname); 81 to = pathname; 82 } 83 if ((uintptr_t)from > (uint32_t)-1) { 84 from = promplat_alloc(OBP_MAXPATHLEN); 85 if (from == NULL) { 86 if (opathname != NULL) 87 promplat_free(pathname, OBP_MAXPATHLEN); 88 return; 89 } 90 } 91 #endif /* PROM_32BIT_ADDRS */ 92 93 promif_preprom(); 94 95 (void) prom_strcpy(from, to); 96 *to = (char)0; 97 98 ci[0] = p1275_ptr2cell("canon"); /* Service name */ 99 ci[1] = (cell_t)3; /* #argument cells */ 100 ci[2] = (cell_t)1; /* #result cells */ 101 ci[3] = p1275_ptr2cell(from); /* Arg1: token */ 102 ci[4] = p1275_ptr2cell(to); /* Arg2: buffer address */ 103 ci[5] = p1275_uint2cell(OBP_MAXPATHLEN); /* Arg3: buffer length */ 104 105 (void) p1275_cif_handler(&ci); 106 107 promif_postprom(); 108 109 #ifdef PROM_32BIT_ADDRS 110 if (opathname != NULL) { 111 (void) prom_strcpy(opathname, pathname); 112 promplat_free(pathname, OBP_MAXPATHLEN); 113 to = pathname = opathname; 114 } 115 if (from != tmp) { 116 (void) prom_strcpy(tmp, from); 117 promplat_free(from, OBP_MAXPATHLEN); 118 from = tmp; 119 } 120 #endif /* PROM_32BIT_ADDRS */ 121 122 /* 123 * workaround for bugid 1218110, the prom strips the 124 * options from the input string ... save options at 125 * at the end of the string if the prom didn't. 126 * NB: The workaround only preserves options in the last 127 * component of the string. 128 */ 129 130 /* 131 * If there are any options in the last component of the 132 * output, the prom has copied them; No workaround required. 133 */ 134 if ((p = prom_strrchr(to, '/')) == 0) 135 return; 136 if ((p = prom_strchr(p, ':')) != 0) 137 return; 138 139 /* 140 * If there are no options in the input ... there's 141 * nothing to preserve; return. 142 */ 143 if ((p = prom_strrchr(from, '/')) == 0) 144 p = from; 145 if ((p = prom_strchr(p, ':')) == 0) 146 return; 147 148 /* 149 * Concatenate the options we found to the end of the output string. 150 */ 151 (void) prom_strcat(to, p); 152 } 153 154 /* 155 * Strip any options strings from an OBP pathname. 156 * Output buffer (to) expected to be as large as input buffer (from). 157 */ 158 void 159 prom_strip_options(char *from, char *to) 160 { 161 while (*from != (char)0) { 162 if (*from == ':') { 163 while ((*from != (char)0) && (*from != '/')) 164 ++from; 165 } else 166 *to++ = *from++; 167 } 168 *to = (char)0; 169 } 170