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