17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*d0495a01Sedp * Common Development and Distribution License (the "License").
6*d0495a01Sedp * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*d0495a01Sedp * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate #include <sys/promif.h>
297c478bd9Sstevel@tonic-gate #include <sys/promimpl.h>
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate char *
prom_path_gettoken(register char * from,register char * to)327c478bd9Sstevel@tonic-gate prom_path_gettoken(register char *from, register char *to)
337c478bd9Sstevel@tonic-gate {
347c478bd9Sstevel@tonic-gate while (*from) {
357c478bd9Sstevel@tonic-gate switch (*from) {
367c478bd9Sstevel@tonic-gate case '/':
377c478bd9Sstevel@tonic-gate case '@':
387c478bd9Sstevel@tonic-gate case ':':
397c478bd9Sstevel@tonic-gate case ',':
407c478bd9Sstevel@tonic-gate *to = '\0';
417c478bd9Sstevel@tonic-gate return (from);
427c478bd9Sstevel@tonic-gate default:
437c478bd9Sstevel@tonic-gate *to++ = *from++;
447c478bd9Sstevel@tonic-gate }
457c478bd9Sstevel@tonic-gate }
467c478bd9Sstevel@tonic-gate *to = '\0';
477c478bd9Sstevel@tonic-gate return (from);
487c478bd9Sstevel@tonic-gate }
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate * Given an OBP pathname, do the best we can to fully expand
527c478bd9Sstevel@tonic-gate * the OBP pathname, in place in the callers buffer.
537c478bd9Sstevel@tonic-gate *
547c478bd9Sstevel@tonic-gate * If we have to complete the addrspec of any component, we can
557c478bd9Sstevel@tonic-gate * only handle devices that have a maximum of NREGSPECS "reg" specs.
567c478bd9Sstevel@tonic-gate * We cannot allocate memory inside this function.
577c478bd9Sstevel@tonic-gate */
587c478bd9Sstevel@tonic-gate void
prom_pathname(char * pathname)597c478bd9Sstevel@tonic-gate prom_pathname(char *pathname)
607c478bd9Sstevel@tonic-gate {
61*d0495a01Sedp char tmp[OBP_MAXPATHLEN];
62*d0495a01Sedp char *from = tmp;
637c478bd9Sstevel@tonic-gate char *to = pathname;
647c478bd9Sstevel@tonic-gate char *p;
657c478bd9Sstevel@tonic-gate cell_t ci[7];
667c478bd9Sstevel@tonic-gate #ifdef PROM_32BIT_ADDRS
677c478bd9Sstevel@tonic-gate char *opathname = NULL;
68*d0495a01Sedp #endif /* PROM_32BIT_ADDRS */
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate if ((to == (char *)0) || (*to == (char)0))
717c478bd9Sstevel@tonic-gate return;
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate #ifdef PROM_32BIT_ADDRS
747c478bd9Sstevel@tonic-gate if ((uintptr_t)pathname > (uint32_t)-1) {
757c478bd9Sstevel@tonic-gate opathname = pathname;
767c478bd9Sstevel@tonic-gate pathname = promplat_alloc(OBP_MAXPATHLEN);
777c478bd9Sstevel@tonic-gate if (pathname == NULL) {
787c478bd9Sstevel@tonic-gate return;
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate (void) prom_strcpy(pathname, opathname);
817c478bd9Sstevel@tonic-gate to = pathname;
827c478bd9Sstevel@tonic-gate }
83*d0495a01Sedp if ((uintptr_t)from > (uint32_t)-1) {
84*d0495a01Sedp from = promplat_alloc(OBP_MAXPATHLEN);
85*d0495a01Sedp if (from == NULL) {
86*d0495a01Sedp if (opathname != NULL)
87*d0495a01Sedp promplat_free(pathname, OBP_MAXPATHLEN);
88*d0495a01Sedp return;
89*d0495a01Sedp }
90*d0495a01Sedp }
91*d0495a01Sedp #endif /* PROM_32BIT_ADDRS */
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate promif_preprom();
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate (void) prom_strcpy(from, to);
967c478bd9Sstevel@tonic-gate *to = (char)0;
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate ci[0] = p1275_ptr2cell("canon"); /* Service name */
997c478bd9Sstevel@tonic-gate ci[1] = (cell_t)3; /* #argument cells */
1007c478bd9Sstevel@tonic-gate ci[2] = (cell_t)1; /* #result cells */
1017c478bd9Sstevel@tonic-gate ci[3] = p1275_ptr2cell(from); /* Arg1: token */
1027c478bd9Sstevel@tonic-gate ci[4] = p1275_ptr2cell(to); /* Arg2: buffer address */
1037c478bd9Sstevel@tonic-gate ci[5] = p1275_uint2cell(OBP_MAXPATHLEN); /* Arg3: buffer length */
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate (void) p1275_cif_handler(&ci);
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate promif_postprom();
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate #ifdef PROM_32BIT_ADDRS
1107c478bd9Sstevel@tonic-gate if (opathname != NULL) {
1117c478bd9Sstevel@tonic-gate (void) prom_strcpy(opathname, pathname);
1127c478bd9Sstevel@tonic-gate promplat_free(pathname, OBP_MAXPATHLEN);
1137c478bd9Sstevel@tonic-gate to = pathname = opathname;
1147c478bd9Sstevel@tonic-gate }
115*d0495a01Sedp if (from != tmp) {
116*d0495a01Sedp (void) prom_strcpy(tmp, from);
117*d0495a01Sedp promplat_free(from, OBP_MAXPATHLEN);
118*d0495a01Sedp from = tmp;
119*d0495a01Sedp }
120*d0495a01Sedp #endif /* PROM_32BIT_ADDRS */
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate /*
1237c478bd9Sstevel@tonic-gate * workaround for bugid 1218110, the prom strips the
1247c478bd9Sstevel@tonic-gate * options from the input string ... save options at
1257c478bd9Sstevel@tonic-gate * at the end of the string if the prom didn't.
1267c478bd9Sstevel@tonic-gate * NB: The workaround only preserves options in the last
1277c478bd9Sstevel@tonic-gate * component of the string.
1287c478bd9Sstevel@tonic-gate */
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate /*
1317c478bd9Sstevel@tonic-gate * If there are any options in the last component of the
1327c478bd9Sstevel@tonic-gate * output, the prom has copied them; No workaround required.
1337c478bd9Sstevel@tonic-gate */
1347c478bd9Sstevel@tonic-gate if ((p = prom_strrchr(to, '/')) == 0)
1357c478bd9Sstevel@tonic-gate return;
1367c478bd9Sstevel@tonic-gate if ((p = prom_strchr(p, ':')) != 0)
1377c478bd9Sstevel@tonic-gate return;
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate /*
1407c478bd9Sstevel@tonic-gate * If there are no options in the input ... there's
1417c478bd9Sstevel@tonic-gate * nothing to preserve; return.
1427c478bd9Sstevel@tonic-gate */
1437c478bd9Sstevel@tonic-gate if ((p = prom_strrchr(from, '/')) == 0)
1447c478bd9Sstevel@tonic-gate p = from;
1457c478bd9Sstevel@tonic-gate if ((p = prom_strchr(p, ':')) == 0)
1467c478bd9Sstevel@tonic-gate return;
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate * Concatenate the options we found to the end of the output string.
1507c478bd9Sstevel@tonic-gate */
1517c478bd9Sstevel@tonic-gate (void) prom_strcat(to, p);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate /*
1557c478bd9Sstevel@tonic-gate * Strip any options strings from an OBP pathname.
1567c478bd9Sstevel@tonic-gate * Output buffer (to) expected to be as large as input buffer (from).
1577c478bd9Sstevel@tonic-gate */
1587c478bd9Sstevel@tonic-gate void
prom_strip_options(char * from,char * to)1597c478bd9Sstevel@tonic-gate prom_strip_options(char *from, char *to)
1607c478bd9Sstevel@tonic-gate {
1617c478bd9Sstevel@tonic-gate while (*from != (char)0) {
1627c478bd9Sstevel@tonic-gate if (*from == ':') {
1637c478bd9Sstevel@tonic-gate while ((*from != (char)0) && (*from != '/'))
1647c478bd9Sstevel@tonic-gate ++from;
1657c478bd9Sstevel@tonic-gate } else
1667c478bd9Sstevel@tonic-gate *to++ = *from++;
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate *to = (char)0;
1697c478bd9Sstevel@tonic-gate }
170