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 /*
23  * Copyright 2008 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 int
prom_fopen(ihandle_t fsih,char * path)33 prom_fopen(ihandle_t fsih, char *path)
34 {
35 	cell_t ci[10];
36 	size_t len;
37 
38 #ifdef PROM_32BIT_ADDRS
39 	char *opath = NULL;
40 
41 	if ((uintptr_t)path > (uint32_t)-1) {
42 		opath = path;
43 		len = prom_strlen(opath) + 1; /* include terminating NUL */
44 		path = promplat_alloc(len);
45 		if (path == NULL)
46 			return (0);
47 		(void) prom_strcpy(path, opath);
48 	}
49 #endif
50 	len = prom_strlen(path);
51 
52 	promif_preprom();
53 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
54 	ci[1] = (cell_t)4;			/* #argument cells */
55 	ci[2] = (cell_t)3;			/* #result cells */
56 	ci[3] = p1275_ptr2cell("open-file");	/* Arg1: Method name */
57 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
58 	ci[5] = p1275_uint2cell(len);		/* Arg3: Len */
59 	ci[6] = p1275_ptr2cell(path);		/* Arg4: Pathname */
60 
61 	(void) p1275_cif_handler(&ci);
62 
63 	promif_postprom();
64 
65 #ifdef PROM_32BIT_ADDRS
66 	if (opath != NULL)
67 		promplat_free(path, len + 1);
68 #endif
69 
70 	if (ci[7] != 0)				/* Catch result */
71 		return (-1);
72 
73 	if (ci[8] == 0)				/* Res1: failed */
74 		return (-1);
75 
76 	return (p1275_cell2int(ci[9]));		/* Res2: fd */
77 }
78 
79 int
prom_volopen(ihandle_t fsih,char * path)80 prom_volopen(ihandle_t fsih, char *path)
81 {
82 	cell_t ci[10];
83 	size_t len;
84 
85 #ifdef PROM_32BIT_ADDRS
86 	char *opath = NULL;
87 
88 	if ((uintptr_t)path > (uint32_t)-1) {
89 		opath = path;
90 		len = prom_strlen(opath) + 1; /* include terminating NUL */
91 		path = promplat_alloc(len);
92 		if (path == NULL)
93 			return (0);
94 		(void) prom_strcpy(path, opath);
95 	}
96 #endif
97 	len = prom_strlen(path);
98 
99 	promif_preprom();
100 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
101 	ci[1] = (cell_t)4;			/* #argument cells */
102 	ci[2] = (cell_t)3;			/* #result cells */
103 	ci[3] = p1275_ptr2cell("open-volume");	/* Arg1: Method name */
104 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
105 	ci[5] = p1275_uint2cell(len);		/* Arg3: Len */
106 	ci[6] = p1275_ptr2cell(path);		/* Arg4: Pathname */
107 
108 	(void) p1275_cif_handler(&ci);
109 
110 	promif_postprom();
111 
112 #ifdef PROM_32BIT_ADDRS
113 	if (opath != NULL)
114 		promplat_free(path, len + 1);
115 #endif
116 
117 	if (ci[7] != 0)				/* Catch result */
118 		return (-1);
119 
120 	if (ci[8] == 0)				/* Res1: failed */
121 		return (-1);
122 
123 	return (p1275_cell2int(ci[9]));		/* Res2: fd */
124 }
125 
126 int
prom_fseek(ihandle_t fsih,int fd,unsigned long long offset)127 prom_fseek(ihandle_t fsih, int fd, unsigned long long offset)
128 {
129 	cell_t ci[10];
130 
131 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
132 	ci[1] = (cell_t)4;			/* #argument cells */
133 	ci[2] = (cell_t)3;			/* #result cells */
134 	ci[3] = p1275_ptr2cell("seek-file");	/* Arg1: Method name */
135 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
136 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
137 	ci[6] = p1275_ull2cell_low(offset);	/* Arg4: Offset */
138 
139 	promif_preprom();
140 	(void) p1275_cif_handler(&ci);
141 	promif_postprom();
142 
143 	if (ci[7] != 0)				/* Catch result */
144 		return (-1);
145 
146 	if (ci[8] == 0)				/* Res1: failed */
147 		return (-1);
148 
149 	return (p1275_cell2int(ci[9]));		/* Res2: off */
150 }
151 
152 
153 int
prom_fread(ihandle_t fsih,int fd,caddr_t buf,size_t len)154 prom_fread(ihandle_t fsih, int fd, caddr_t buf, size_t len)
155 {
156 	cell_t ci[10];
157 #ifdef PROM_32BIT_ADDRS
158 	caddr_t obuf = NULL;
159 
160 	if ((uintptr_t)buf > (uint32_t)-1) {
161 		obuf = buf;
162 		buf = promplat_alloc(len);
163 		if (buf == NULL)
164 			return (-1);
165 	}
166 #endif
167 
168 	promif_preprom();
169 
170 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
171 	ci[1] = (cell_t)5;			/* #argument cells */
172 	ci[2] = (cell_t)2;			/* #result cells */
173 	ci[3] = p1275_ptr2cell("read-file");	/* Arg1: Method name */
174 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
175 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
176 	ci[6] = p1275_uint2cell(len);		/* Arg4: buffer length */
177 	ci[7] = p1275_ptr2cell(buf);		/* Arg5: buffer address */
178 
179 	(void) p1275_cif_handler(&ci);
180 
181 	promif_postprom();
182 
183 #ifdef PROM_32BIT_ADDRS
184 	if (obuf != NULL) {
185 		promplat_bcopy(buf, obuf, len);
186 		promplat_free(buf, len);
187 	}
188 #endif
189 
190 	if (ci[8] != 0)				/* Catch result */
191 		return (-1);
192 
193 	return (p1275_cell2int(ci[9]));		/* Res2: actual length */
194 }
195 
196 int
prom_fsize(ihandle_t fsih,int fd,size_t * size)197 prom_fsize(ihandle_t fsih, int fd, size_t *size)
198 {
199 	cell_t ci[8];
200 
201 	promif_preprom();
202 
203 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
204 	ci[1] = (cell_t)3;			/* #argument cells */
205 	ci[2] = (cell_t)2;			/* #result cells */
206 	ci[3] = p1275_ptr2cell("size-file");	/* Arg1: Method name */
207 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
208 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
209 
210 	(void) p1275_cif_handler(&ci);
211 
212 	promif_postprom();
213 
214 	if (ci[6] != 0)				/* Catch result */
215 		return (-1);
216 
217 	*size = p1275_cell2uint(ci[7]);		/* Res2: size */
218 	return (0);
219 }
220 
221 
222 int
prom_compinfo(ihandle_t fsih,int fd,int * iscmp,size_t * fsize,size_t * bsize)223 prom_compinfo(ihandle_t fsih, int fd, int *iscmp, size_t *fsize, size_t *bsize)
224 {
225 	cell_t ci[10];
226 
227 	promif_preprom();
228 
229 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
230 	ci[1] = (cell_t)3;			/* #argument cells */
231 	ci[2] = (cell_t)4;			/* #result cells */
232 	ci[3] = p1275_ptr2cell("cinfo-file");	/* Arg1: Method name */
233 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
234 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
235 
236 	(void) p1275_cif_handler(&ci);
237 
238 	promif_postprom();
239 
240 	if (ci[6] != 0)				/* Catch result */
241 		return (-1);
242 
243 	*iscmp = p1275_cell2int(ci[7]);		/* Res2: iscmp */
244 	*fsize = p1275_cell2uint(ci[8]);	/* Res3: fsize */
245 	*bsize = p1275_cell2uint(ci[9]);	/* Res4: bsize */
246 	return (0);
247 }
248 
249 void
prom_fclose(ihandle_t fsih,int fd)250 prom_fclose(ihandle_t fsih, int fd)
251 {
252 	cell_t ci[7];
253 
254 	ci[0] = p1275_ptr2cell("call-method");	/* Service name */
255 	ci[1] = (cell_t)3;			/* #argument cells */
256 	ci[2] = (cell_t)1;			/* #result cells */
257 	ci[3] = p1275_ptr2cell("close-file");	/* Arg1: Method name */
258 	ci[4] = p1275_ihandle2cell(fsih);	/* Arg2: fs ihandle */
259 	ci[5] = p1275_int2cell(fd);		/* Arg3: file desc */
260 
261 	promif_preprom();
262 	(void) p1275_cif_handler(&ci);
263 	promif_postprom();
264 
265 }
266