1986fd29aSsetje /*
2986fd29aSsetje  * CDDL HEADER START
3986fd29aSsetje  *
4986fd29aSsetje  * The contents of this file are subject to the terms of the
5986fd29aSsetje  * Common Development and Distribution License (the "License").
6986fd29aSsetje  * You may not use this file except in compliance with the License.
7986fd29aSsetje  *
8986fd29aSsetje  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9986fd29aSsetje  * or http://www.opensolaris.org/os/licensing.
10986fd29aSsetje  * See the License for the specific language governing permissions
11986fd29aSsetje  * and limitations under the License.
12986fd29aSsetje  *
13986fd29aSsetje  * When distributing Covered Code, include this CDDL HEADER in each
14986fd29aSsetje  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15986fd29aSsetje  * If applicable, add the following below this CDDL HEADER, with the
16986fd29aSsetje  * fields enclosed by brackets "[]" replaced with your own identifying
17986fd29aSsetje  * information: Portions Copyright [yyyy] [name of copyright owner]
18986fd29aSsetje  *
19986fd29aSsetje  * CDDL HEADER END
20986fd29aSsetje  */
21986fd29aSsetje 
22986fd29aSsetje /*
23*e7cbe64fSgw  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24986fd29aSsetje  * Use is subject to license terms.
25986fd29aSsetje  */
26986fd29aSsetje 
27986fd29aSsetje #pragma ident	"%Z%%M%	%I%	%E% SMI"
28986fd29aSsetje 
29986fd29aSsetje #include <sys/promif.h>
30986fd29aSsetje #include <sys/promimpl.h>
31986fd29aSsetje 
32986fd29aSsetje int
prom_fopen(ihandle_t fsih,char * path)33986fd29aSsetje prom_fopen(ihandle_t fsih, char *path)
34986fd29aSsetje {
35986fd29aSsetje 	cell_t ci[10];
36986fd29aSsetje 	size_t len;
37986fd29aSsetje 
38986fd29aSsetje #ifdef PROM_32BIT_ADDRS
39986fd29aSsetje 	char *opath = NULL;
40986fd29aSsetje 
41986fd29aSsetje 	if ((uintptr_t)path > (uint32_t)-1) {
42986fd29aSsetje 		opath = path;
43986fd29aSsetje 		len = prom_strlen(opath) + 1; /* include terminating NUL */
44986fd29aSsetje 		path = promplat_alloc(len);
45986fd29aSsetje 		if (path == NULL)
46986fd29aSsetje 			return (0);
47986fd29aSsetje 		(void) prom_strcpy(path, opath);
48986fd29aSsetje 	}
49986fd29aSsetje #endif
50986fd29aSsetje 	len = prom_strlen(path);
51986fd29aSsetje 
52986fd29aSsetje 	promif_preprom();
53986fd29aSsetje 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
54986fd29aSsetje 	ci[1] = (cell_t)4;			/* #argument cells */
55986fd29aSsetje 	ci[2] = (cell_t)3;			/* #result cells */
56986fd29aSsetje 	ci[3] = p1275_ptr2cell("open-file");	/* Arg1: Method name */
57986fd29aSsetje 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
58986fd29aSsetje 	ci[5] = p1275_uint2cell(len);		/* Arg3: Len */
59986fd29aSsetje 	ci[6] = p1275_ptr2cell(path);		/* Arg4: Pathname */
60986fd29aSsetje 
61986fd29aSsetje 	(void) p1275_cif_handler(&ci);
62986fd29aSsetje 
63986fd29aSsetje 	promif_postprom();
64986fd29aSsetje 
65986fd29aSsetje #ifdef PROM_32BIT_ADDRS
66986fd29aSsetje 	if (opath != NULL)
67986fd29aSsetje 		promplat_free(path, len + 1);
68986fd29aSsetje #endif
69986fd29aSsetje 
70986fd29aSsetje 	if (ci[7] != 0)				/* Catch result */
71986fd29aSsetje 		return (-1);
72986fd29aSsetje 
73986fd29aSsetje 	if (ci[8] == 0)				/* Res1: failed */
74986fd29aSsetje 		return (-1);
75986fd29aSsetje 
76986fd29aSsetje 	return (p1275_cell2int(ci[9]));		/* Res2: fd */
77986fd29aSsetje }
78986fd29aSsetje 
79*e7cbe64fSgw int
prom_volopen(ihandle_t fsih,char * path)80*e7cbe64fSgw prom_volopen(ihandle_t fsih, char *path)
81*e7cbe64fSgw {
82*e7cbe64fSgw 	cell_t ci[10];
83*e7cbe64fSgw 	size_t len;
84*e7cbe64fSgw 
85*e7cbe64fSgw #ifdef PROM_32BIT_ADDRS
86*e7cbe64fSgw 	char *opath = NULL;
87*e7cbe64fSgw 
88*e7cbe64fSgw 	if ((uintptr_t)path > (uint32_t)-1) {
89*e7cbe64fSgw 		opath = path;
90*e7cbe64fSgw 		len = prom_strlen(opath) + 1; /* include terminating NUL */
91*e7cbe64fSgw 		path = promplat_alloc(len);
92*e7cbe64fSgw 		if (path == NULL)
93*e7cbe64fSgw 			return (0);
94*e7cbe64fSgw 		(void) prom_strcpy(path, opath);
95*e7cbe64fSgw 	}
96*e7cbe64fSgw #endif
97*e7cbe64fSgw 	len = prom_strlen(path);
98*e7cbe64fSgw 
99*e7cbe64fSgw 	promif_preprom();
100*e7cbe64fSgw 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
101*e7cbe64fSgw 	ci[1] = (cell_t)4;			/* #argument cells */
102*e7cbe64fSgw 	ci[2] = (cell_t)3;			/* #result cells */
103*e7cbe64fSgw 	ci[3] = p1275_ptr2cell("open-volume");	/* Arg1: Method name */
104*e7cbe64fSgw 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
105*e7cbe64fSgw 	ci[5] = p1275_uint2cell(len);		/* Arg3: Len */
106*e7cbe64fSgw 	ci[6] = p1275_ptr2cell(path);		/* Arg4: Pathname */
107*e7cbe64fSgw 
108*e7cbe64fSgw 	(void) p1275_cif_handler(&ci);
109*e7cbe64fSgw 
110*e7cbe64fSgw 	promif_postprom();
111*e7cbe64fSgw 
112*e7cbe64fSgw #ifdef PROM_32BIT_ADDRS
113*e7cbe64fSgw 	if (opath != NULL)
114*e7cbe64fSgw 		promplat_free(path, len + 1);
115*e7cbe64fSgw #endif
116*e7cbe64fSgw 
117*e7cbe64fSgw 	if (ci[7] != 0)				/* Catch result */
118*e7cbe64fSgw 		return (-1);
119*e7cbe64fSgw 
120*e7cbe64fSgw 	if (ci[8] == 0)				/* Res1: failed */
121*e7cbe64fSgw 		return (-1);
122*e7cbe64fSgw 
123*e7cbe64fSgw 	return (p1275_cell2int(ci[9]));		/* Res2: fd */
124*e7cbe64fSgw }
125986fd29aSsetje 
126986fd29aSsetje int
prom_fseek(ihandle_t fsih,int fd,unsigned long long offset)127986fd29aSsetje prom_fseek(ihandle_t fsih, int fd, unsigned long long offset)
128986fd29aSsetje {
129986fd29aSsetje 	cell_t ci[10];
130986fd29aSsetje 
131986fd29aSsetje 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
132986fd29aSsetje 	ci[1] = (cell_t)4;			/* #argument cells */
133986fd29aSsetje 	ci[2] = (cell_t)3;			/* #result cells */
134986fd29aSsetje 	ci[3] = p1275_ptr2cell("seek-file");	/* Arg1: Method name */
135986fd29aSsetje 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
136986fd29aSsetje 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
137986fd29aSsetje 	ci[6] = p1275_ull2cell_low(offset);	/* Arg4: Offset */
138986fd29aSsetje 
139986fd29aSsetje 	promif_preprom();
140986fd29aSsetje 	(void) p1275_cif_handler(&ci);
141986fd29aSsetje 	promif_postprom();
142986fd29aSsetje 
143986fd29aSsetje 	if (ci[7] != 0)				/* Catch result */
144986fd29aSsetje 		return (-1);
145986fd29aSsetje 
146986fd29aSsetje 	if (ci[8] == 0)				/* Res1: failed */
147986fd29aSsetje 		return (-1);
148986fd29aSsetje 
149986fd29aSsetje 	return (p1275_cell2int(ci[9]));		/* Res2: off */
150986fd29aSsetje }
151986fd29aSsetje 
152986fd29aSsetje 
153986fd29aSsetje int
prom_fread(ihandle_t fsih,int fd,caddr_t buf,size_t len)154986fd29aSsetje prom_fread(ihandle_t fsih, int fd, caddr_t buf, size_t len)
155986fd29aSsetje {
156986fd29aSsetje 	cell_t ci[10];
157986fd29aSsetje #ifdef PROM_32BIT_ADDRS
158986fd29aSsetje 	caddr_t obuf = NULL;
159986fd29aSsetje 
160986fd29aSsetje 	if ((uintptr_t)buf > (uint32_t)-1) {
161986fd29aSsetje 		obuf = buf;
162986fd29aSsetje 		buf = promplat_alloc(len);
163986fd29aSsetje 		if (buf == NULL)
164986fd29aSsetje 			return (-1);
165986fd29aSsetje 	}
166986fd29aSsetje #endif
167986fd29aSsetje 
168986fd29aSsetje 	promif_preprom();
169986fd29aSsetje 
170986fd29aSsetje 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
171986fd29aSsetje 	ci[1] = (cell_t)5;			/* #argument cells */
172986fd29aSsetje 	ci[2] = (cell_t)2;			/* #result cells */
173986fd29aSsetje 	ci[3] = p1275_ptr2cell("read-file");	/* Arg1: Method name */
174986fd29aSsetje 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
175986fd29aSsetje 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
176986fd29aSsetje 	ci[6] = p1275_uint2cell(len);		/* Arg4: buffer length */
177986fd29aSsetje 	ci[7] = p1275_ptr2cell(buf);		/* Arg5: buffer address */
178986fd29aSsetje 
179986fd29aSsetje 	(void) p1275_cif_handler(&ci);
180986fd29aSsetje 
181986fd29aSsetje 	promif_postprom();
182986fd29aSsetje 
183986fd29aSsetje #ifdef PROM_32BIT_ADDRS
184986fd29aSsetje 	if (obuf != NULL) {
185986fd29aSsetje 		promplat_bcopy(buf, obuf, len);
186986fd29aSsetje 		promplat_free(buf, len);
187986fd29aSsetje 	}
188986fd29aSsetje #endif
189986fd29aSsetje 
190986fd29aSsetje 	if (ci[8] != 0)				/* Catch result */
191986fd29aSsetje 		return (-1);
192986fd29aSsetje 
193986fd29aSsetje 	return (p1275_cell2int(ci[9]));		/* Res2: actual length */
194986fd29aSsetje }
195986fd29aSsetje 
196986fd29aSsetje int
prom_fsize(ihandle_t fsih,int fd,size_t * size)197986fd29aSsetje prom_fsize(ihandle_t fsih, int fd, size_t *size)
198986fd29aSsetje {
199986fd29aSsetje 	cell_t ci[8];
200986fd29aSsetje 
201986fd29aSsetje 	promif_preprom();
202986fd29aSsetje 
203986fd29aSsetje 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
204986fd29aSsetje 	ci[1] = (cell_t)3;			/* #argument cells */
205986fd29aSsetje 	ci[2] = (cell_t)2;			/* #result cells */
206986fd29aSsetje 	ci[3] = p1275_ptr2cell("size-file");	/* Arg1: Method name */
207986fd29aSsetje 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
208986fd29aSsetje 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
209986fd29aSsetje 
210986fd29aSsetje 	(void) p1275_cif_handler(&ci);
211986fd29aSsetje 
212986fd29aSsetje 	promif_postprom();
213986fd29aSsetje 
214986fd29aSsetje 	if (ci[6] != 0)				/* Catch result */
215986fd29aSsetje 		return (-1);
216986fd29aSsetje 
217986fd29aSsetje 	*size = p1275_cell2uint(ci[7]);		/* Res2: size */
218986fd29aSsetje 	return (0);
219986fd29aSsetje }
220986fd29aSsetje 
221986fd29aSsetje 
222986fd29aSsetje int
prom_compinfo(ihandle_t fsih,int fd,int * iscmp,size_t * fsize,size_t * bsize)223986fd29aSsetje prom_compinfo(ihandle_t fsih, int fd, int *iscmp, size_t *fsize, size_t *bsize)
224986fd29aSsetje {
225986fd29aSsetje 	cell_t ci[10];
226986fd29aSsetje 
227986fd29aSsetje 	promif_preprom();
228986fd29aSsetje 
229986fd29aSsetje 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
230986fd29aSsetje 	ci[1] = (cell_t)3;			/* #argument cells */
231986fd29aSsetje 	ci[2] = (cell_t)4;			/* #result cells */
232986fd29aSsetje 	ci[3] = p1275_ptr2cell("cinfo-file");	/* Arg1: Method name */
233986fd29aSsetje 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
234986fd29aSsetje 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
235986fd29aSsetje 
236986fd29aSsetje 	(void) p1275_cif_handler(&ci);
237986fd29aSsetje 
238986fd29aSsetje 	promif_postprom();
239986fd29aSsetje 
240986fd29aSsetje 	if (ci[6] != 0)				/* Catch result */
241986fd29aSsetje 		return (-1);
242986fd29aSsetje 
243986fd29aSsetje 	*iscmp = p1275_cell2int(ci[7]);		/* Res2: iscmp */
244986fd29aSsetje 	*fsize = p1275_cell2uint(ci[8]);	/* Res3: fsize */
245986fd29aSsetje 	*bsize = p1275_cell2uint(ci[9]);	/* Res4: bsize */
246986fd29aSsetje 	return (0);
247986fd29aSsetje }
248986fd29aSsetje 
249986fd29aSsetje void
prom_fclose(ihandle_t fsih,int fd)250986fd29aSsetje prom_fclose(ihandle_t fsih, int fd)
251986fd29aSsetje {
252986fd29aSsetje 	cell_t ci[7];
253986fd29aSsetje 
254986fd29aSsetje 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
255986fd29aSsetje 	ci[1] = (cell_t)3;			/* #argument cells */
256986fd29aSsetje 	ci[2] = (cell_t)1;			/* #result cells */
257986fd29aSsetje 	ci[3] = p1275_ptr2cell("close-file");	/* Arg1: Method name */
258986fd29aSsetje 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
259986fd29aSsetje 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
260986fd29aSsetje 
261986fd29aSsetje 	promif_preprom();
262986fd29aSsetje 	(void) p1275_cif_handler(&ci);
263986fd29aSsetje 	promif_postprom();
264986fd29aSsetje 
265986fd29aSsetje }
266