netbsd32_ioctl.c revision 1.5.4.1 1 1.5.4.1 mrg /* $NetBSD: netbsd32_ioctl.c,v 1.5.4.1 2000/08/26 01:08:57 mrg Exp $ */
2 1.1 mrg
3 1.1 mrg /*
4 1.1 mrg * Copyright (c) 1998 Matthew R. Green
5 1.1 mrg * All rights reserved.
6 1.1 mrg *
7 1.1 mrg * Redistribution and use in source and binary forms, with or without
8 1.1 mrg * modification, are permitted provided that the following conditions
9 1.1 mrg * are met:
10 1.1 mrg * 1. Redistributions of source code must retain the above copyright
11 1.1 mrg * notice, this list of conditions and the following disclaimer.
12 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 mrg * notice, this list of conditions and the following disclaimer in the
14 1.1 mrg * documentation and/or other materials provided with the distribution.
15 1.1 mrg * 3. The name of the author may not be used to endorse or promote products
16 1.1 mrg * derived from this software without specific prior written permission.
17 1.1 mrg *
18 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 1.1 mrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 1.1 mrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 1.1 mrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 1.1 mrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 1.1 mrg * SUCH DAMAGE.
29 1.1 mrg */
30 1.1 mrg
31 1.1 mrg /*
32 1.2 mrg * handle ioctl conversions from netbsd32 -> sparc64
33 1.1 mrg */
34 1.1 mrg
35 1.1 mrg #include <sys/param.h>
36 1.1 mrg #include <sys/systm.h>
37 1.5.4.1 mrg #include <sys/filedesc.h>
38 1.5.4.1 mrg #include <sys/ioctl.h>
39 1.5.4.1 mrg #include <sys/file.h>
40 1.5.4.1 mrg #include <sys/proc.h>
41 1.5.4.1 mrg #include <sys/socketvar.h>
42 1.1 mrg #include <sys/audioio.h>
43 1.1 mrg #include <sys/disklabel.h>
44 1.1 mrg #include <sys/dkio.h>
45 1.1 mrg #include <sys/malloc.h>
46 1.1 mrg #include <sys/proc.h>
47 1.1 mrg #include <sys/sockio.h>
48 1.1 mrg #include <sys/socket.h>
49 1.1 mrg #include <sys/ttycom.h>
50 1.1 mrg #include <sys/mount.h>
51 1.1 mrg #include <sys/syscallargs.h>
52 1.1 mrg
53 1.1 mrg #include <machine/fbio.h>
54 1.1 mrg #include <machine/openpromio.h>
55 1.1 mrg
56 1.1 mrg #include <net/if.h>
57 1.1 mrg #include <net/route.h>
58 1.1 mrg
59 1.1 mrg #include <netinet/in.h>
60 1.1 mrg #include <netinet/in_var.h>
61 1.1 mrg #include <netinet/igmp.h>
62 1.1 mrg #include <netinet/igmp_var.h>
63 1.1 mrg #include <netinet/ip_mroute.h>
64 1.1 mrg
65 1.2 mrg #include <compat/netbsd32/netbsd32.h>
66 1.2 mrg #include <compat/netbsd32/netbsd32_ioctl.h>
67 1.2 mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
68 1.1 mrg
69 1.5.4.1 mrg
70 1.1 mrg void
71 1.5.4.1 mrg netbsd32_to_fbcmap(s32p, p, cmd)
72 1.2 mrg struct netbsd32_fbcmap *s32p;
73 1.1 mrg struct fbcmap *p;
74 1.5.4.1 mrg u_long cmd;
75 1.1 mrg {
76 1.1 mrg
77 1.1 mrg p->index = s32p->index;
78 1.1 mrg p->count = s32p->count;
79 1.1 mrg p->red = (u_char *)(u_long)s32p->red;
80 1.1 mrg p->green = (u_char *)(u_long)s32p->green;
81 1.1 mrg p->blue = (u_char *)(u_long)s32p->blue;
82 1.1 mrg }
83 1.1 mrg
84 1.1 mrg void
85 1.5.4.1 mrg netbsd32_to_fbcursor(s32p, p, cmd)
86 1.2 mrg struct netbsd32_fbcursor *s32p;
87 1.1 mrg struct fbcursor *p;
88 1.5.4.1 mrg u_long cmd;
89 1.1 mrg {
90 1.1 mrg
91 1.1 mrg p->set = s32p->set;
92 1.1 mrg p->enable = s32p->enable;
93 1.1 mrg p->pos = s32p->pos;
94 1.1 mrg p->hot = s32p->hot;
95 1.5.4.1 mrg netbsd32_to_fbcmap(&s32p->cmap, &p->cmap, cmd);
96 1.1 mrg p->size = s32p->size;
97 1.1 mrg p->image = (char *)(u_long)s32p->image;
98 1.1 mrg p->mask = (char *)(u_long)s32p->mask;
99 1.1 mrg }
100 1.1 mrg
101 1.1 mrg void
102 1.5.4.1 mrg netbsd32_to_opiocdesc(s32p, p, cmd)
103 1.2 mrg struct netbsd32_opiocdesc *s32p;
104 1.1 mrg struct opiocdesc *p;
105 1.5.4.1 mrg u_long cmd;
106 1.1 mrg {
107 1.1 mrg
108 1.1 mrg p->op_nodeid = s32p->op_nodeid;
109 1.1 mrg p->op_namelen = s32p->op_namelen;
110 1.1 mrg p->op_name = (char *)(u_long)s32p->op_name;
111 1.1 mrg p->op_buflen = s32p->op_buflen;
112 1.1 mrg p->op_buf = (char *)(u_long)s32p->op_buf;
113 1.1 mrg }
114 1.1 mrg
115 1.1 mrg void
116 1.5.4.1 mrg netbsd32_to_partinfo(s32p, p, cmd)
117 1.2 mrg struct netbsd32_partinfo *s32p;
118 1.1 mrg struct partinfo *p;
119 1.5.4.1 mrg u_long cmd;
120 1.1 mrg {
121 1.1 mrg
122 1.1 mrg p->disklab = (struct disklabel *)(u_long)s32p->disklab;
123 1.1 mrg p->part = (struct partition *)(u_long)s32p->part;
124 1.1 mrg }
125 1.1 mrg
126 1.1 mrg void
127 1.5.4.1 mrg netbsd32_to_format_op(s32p, p, cmd)
128 1.2 mrg struct netbsd32_format_op *s32p;
129 1.1 mrg struct format_op *p;
130 1.5.4.1 mrg u_long cmd;
131 1.1 mrg {
132 1.1 mrg
133 1.1 mrg p->df_buf = (char *)(u_long)s32p->df_buf;
134 1.1 mrg p->df_count = s32p->df_count;
135 1.1 mrg p->df_startblk = s32p->df_startblk;
136 1.1 mrg memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg));
137 1.1 mrg }
138 1.1 mrg
139 1.1 mrg #if 0 /* XXX see below */
140 1.1 mrg void
141 1.2 mrg netbsd32_to_ifreq(s32p, p, cmd)
142 1.2 mrg struct netbsd32_ifreq *s32p;
143 1.1 mrg struct ifreq *p;
144 1.1 mrg u_long cmd; /* XXX unused yet */
145 1.1 mrg {
146 1.1 mrg
147 1.1 mrg /*
148 1.1 mrg * XXX
149 1.1 mrg * struct ifreq says the same, but sometimes the ifr_data
150 1.1 mrg * union member needs to be converted to 64 bits... this
151 1.1 mrg * is very driver specific and so we ignore it for now..
152 1.1 mrg */
153 1.1 mrg memcpy(p, s32p, sizeof *s32p);
154 1.1 mrg }
155 1.1 mrg #endif
156 1.1 mrg
157 1.1 mrg void
158 1.5.4.1 mrg netbsd32_to_ifconf(s32p, p, cmd)
159 1.2 mrg struct netbsd32_ifconf *s32p;
160 1.1 mrg struct ifconf *p;
161 1.5.4.1 mrg u_long cmd;
162 1.1 mrg {
163 1.1 mrg
164 1.1 mrg p->ifc_len = s32p->ifc_len;
165 1.1 mrg /* ifc_buf & ifc_req are the same size so this works */
166 1.1 mrg p->ifc_buf = (caddr_t)(u_long)s32p->ifc_buf;
167 1.1 mrg }
168 1.1 mrg
169 1.1 mrg void
170 1.5.4.1 mrg netbsd32_to_ifmediareq(s32p, p, cmd)
171 1.2 mrg struct netbsd32_ifmediareq *s32p;
172 1.1 mrg struct ifmediareq *p;
173 1.5.4.1 mrg u_long cmd;
174 1.1 mrg {
175 1.1 mrg
176 1.1 mrg memcpy(p, s32p, sizeof *s32p);
177 1.1 mrg p->ifm_ulist = (int *)(u_long)s32p->ifm_ulist;
178 1.1 mrg }
179 1.1 mrg
180 1.1 mrg void
181 1.5.4.1 mrg netbsd32_to_ifdrv(s32p, p, cmd)
182 1.2 mrg struct netbsd32_ifdrv *s32p;
183 1.1 mrg struct ifdrv *p;
184 1.5.4.1 mrg u_long cmd;
185 1.1 mrg {
186 1.1 mrg
187 1.1 mrg memcpy(p, s32p, sizeof *s32p);
188 1.1 mrg p->ifd_data = (void *)(u_long)s32p->ifd_data;
189 1.1 mrg }
190 1.1 mrg
191 1.1 mrg void
192 1.5.4.1 mrg netbsd32_to_sioc_vif_req(s32p, p, cmd)
193 1.2 mrg struct netbsd32_sioc_vif_req *s32p;
194 1.1 mrg struct sioc_vif_req *p;
195 1.5.4.1 mrg u_long cmd;
196 1.1 mrg {
197 1.1 mrg
198 1.1 mrg p->vifi = s32p->vifi;
199 1.1 mrg p->icount = (u_long)s32p->icount;
200 1.1 mrg p->ocount = (u_long)s32p->ocount;
201 1.1 mrg p->ibytes = (u_long)s32p->ibytes;
202 1.1 mrg p->obytes = (u_long)s32p->obytes;
203 1.1 mrg }
204 1.1 mrg
205 1.1 mrg void
206 1.5.4.1 mrg netbsd32_to_sioc_sg_req(s32p, p, cmd)
207 1.2 mrg struct netbsd32_sioc_sg_req *s32p;
208 1.1 mrg struct sioc_sg_req *p;
209 1.5.4.1 mrg u_long cmd;
210 1.1 mrg {
211 1.1 mrg
212 1.1 mrg p->src = s32p->src;
213 1.1 mrg p->grp = s32p->grp;
214 1.1 mrg p->pktcnt = (u_long)s32p->pktcnt;
215 1.1 mrg p->bytecnt = (u_long)s32p->bytecnt;
216 1.1 mrg p->wrong_if = (u_long)s32p->wrong_if;
217 1.1 mrg }
218 1.1 mrg
219 1.1 mrg /*
220 1.2 mrg * handle ioctl conversions from sparc64 -> netbsd32
221 1.1 mrg */
222 1.1 mrg
223 1.1 mrg void
224 1.2 mrg netbsd32_from_fbcmap(p, s32p)
225 1.1 mrg struct fbcmap *p;
226 1.2 mrg struct netbsd32_fbcmap *s32p;
227 1.1 mrg {
228 1.1 mrg
229 1.1 mrg s32p->index = p->index;
230 1.1 mrg s32p->count = p->count;
231 1.1 mrg /* filled in */
232 1.1 mrg #if 0
233 1.2 mrg s32p->red = (netbsd32_u_charp)p->red;
234 1.2 mrg s32p->green = (netbsd32_u_charp)p->green;
235 1.2 mrg s32p->blue = (netbsd32_u_charp)p->blue;
236 1.1 mrg #endif
237 1.1 mrg }
238 1.1 mrg
239 1.1 mrg void
240 1.2 mrg netbsd32_from_fbcursor(p, s32p)
241 1.1 mrg struct fbcursor *p;
242 1.2 mrg struct netbsd32_fbcursor *s32p;
243 1.1 mrg {
244 1.1 mrg
245 1.1 mrg s32p->set = p->set;
246 1.1 mrg s32p->enable = p->enable;
247 1.1 mrg s32p->pos = p->pos;
248 1.1 mrg s32p->hot = p->hot;
249 1.2 mrg netbsd32_from_fbcmap(&p->cmap, &s32p->cmap);
250 1.1 mrg s32p->size = p->size;
251 1.1 mrg /* filled in */
252 1.1 mrg #if 0
253 1.2 mrg s32p->image = (netbsd32_charp)p->image;
254 1.2 mrg s32p->mask = (netbsd32_charp)p->mask;
255 1.1 mrg #endif
256 1.1 mrg }
257 1.1 mrg
258 1.1 mrg void
259 1.2 mrg netbsd32_from_opiocdesc(p, s32p)
260 1.1 mrg struct opiocdesc *p;
261 1.2 mrg struct netbsd32_opiocdesc *s32p;
262 1.1 mrg {
263 1.1 mrg
264 1.1 mrg s32p->op_nodeid = p->op_nodeid;
265 1.1 mrg s32p->op_namelen = p->op_namelen;
266 1.2 mrg s32p->op_name = (netbsd32_charp)(u_long)p->op_name;
267 1.1 mrg s32p->op_buflen = p->op_buflen;
268 1.2 mrg s32p->op_buf = (netbsd32_charp)(u_long)p->op_buf;
269 1.1 mrg }
270 1.1 mrg
271 1.1 mrg void
272 1.5.4.1 mrg netbsd32_from_partinfo(p, s32p)
273 1.5.4.1 mrg struct partinfo *p;
274 1.5.4.1 mrg struct netbsd32_partinfo *s32p;
275 1.5.4.1 mrg {
276 1.5.4.1 mrg
277 1.5.4.1 mrg s32p->disklab = (netbsd32_disklabel_tp_t)(u_long)p->disklab;
278 1.5.4.1 mrg s32p->part = s32p->part;
279 1.5.4.1 mrg }
280 1.5.4.1 mrg
281 1.5.4.1 mrg void
282 1.2 mrg netbsd32_from_format_op(p, s32p)
283 1.1 mrg struct format_op *p;
284 1.2 mrg struct netbsd32_format_op *s32p;
285 1.1 mrg {
286 1.1 mrg
287 1.1 mrg /* filled in */
288 1.1 mrg #if 0
289 1.2 mrg s32p->df_buf = (netbsd32_charp)p->df_buf;
290 1.1 mrg #endif
291 1.1 mrg s32p->df_count = p->df_count;
292 1.1 mrg s32p->df_startblk = p->df_startblk;
293 1.1 mrg memcpy(s32p->df_reg, p->df_reg, sizeof(p->df_reg));
294 1.1 mrg }
295 1.1 mrg
296 1.1 mrg #if 0 /* XXX see below */
297 1.1 mrg void
298 1.2 mrg netbsd32_from_ifreq(p, s32p, cmd)
299 1.1 mrg struct ifreq *p;
300 1.2 mrg struct netbsd32_ifreq *s32p;
301 1.1 mrg u_long cmd; /* XXX unused yet */
302 1.1 mrg {
303 1.1 mrg
304 1.1 mrg /*
305 1.1 mrg * XXX
306 1.1 mrg * struct ifreq says the same, but sometimes the ifr_data
307 1.1 mrg * union member needs to be converted to 64 bits... this
308 1.1 mrg * is very driver specific and so we ignore it for now..
309 1.1 mrg */
310 1.1 mrg *s32p = *p;
311 1.1 mrg }
312 1.1 mrg #endif
313 1.1 mrg
314 1.1 mrg void
315 1.2 mrg netbsd32_from_ifconf(p, s32p)
316 1.1 mrg struct ifconf *p;
317 1.2 mrg struct netbsd32_ifconf *s32p;
318 1.1 mrg {
319 1.1 mrg
320 1.1 mrg s32p->ifc_len = p->ifc_len;
321 1.1 mrg /* ifc_buf & ifc_req are the same size so this works */
322 1.2 mrg s32p->ifc_buf = (netbsd32_caddr_t)(u_long)p->ifc_buf;
323 1.1 mrg }
324 1.1 mrg
325 1.1 mrg void
326 1.2 mrg netbsd32_from_ifmediareq(p, s32p)
327 1.1 mrg struct ifmediareq *p;
328 1.2 mrg struct netbsd32_ifmediareq *s32p;
329 1.1 mrg {
330 1.1 mrg
331 1.1 mrg memcpy(s32p, p, sizeof *p);
332 1.1 mrg /* filled in? */
333 1.1 mrg #if 0
334 1.2 mrg s32p->ifm_ulist = (netbsd32_intp_t)p->ifm_ulist;
335 1.1 mrg #endif
336 1.1 mrg }
337 1.1 mrg
338 1.1 mrg void
339 1.2 mrg netbsd32_from_ifdrv(p, s32p)
340 1.1 mrg struct ifdrv *p;
341 1.2 mrg struct netbsd32_ifdrv *s32p;
342 1.1 mrg {
343 1.1 mrg
344 1.1 mrg memcpy(s32p, p, sizeof *p);
345 1.1 mrg /* filled in? */
346 1.1 mrg #if 0
347 1.2 mrg s32p->ifm_data = (netbsd32_u_longp_t)p->ifm_data;
348 1.1 mrg #endif
349 1.1 mrg }
350 1.1 mrg
351 1.1 mrg void
352 1.2 mrg netbsd32_from_sioc_vif_req(p, s32p)
353 1.1 mrg struct sioc_vif_req *p;
354 1.2 mrg struct netbsd32_sioc_vif_req *s32p;
355 1.1 mrg {
356 1.1 mrg
357 1.1 mrg s32p->vifi = p->vifi;
358 1.2 mrg s32p->icount = (netbsd32_u_long)p->icount;
359 1.2 mrg s32p->ocount = (netbsd32_u_long)p->ocount;
360 1.2 mrg s32p->ibytes = (netbsd32_u_long)p->ibytes;
361 1.2 mrg s32p->obytes = (netbsd32_u_long)p->obytes;
362 1.1 mrg }
363 1.1 mrg
364 1.1 mrg void
365 1.2 mrg netbsd32_from_sioc_sg_req(p, s32p)
366 1.1 mrg struct sioc_sg_req *p;
367 1.2 mrg struct netbsd32_sioc_sg_req *s32p;
368 1.1 mrg {
369 1.1 mrg
370 1.1 mrg s32p->src = p->src;
371 1.1 mrg s32p->grp = p->grp;
372 1.2 mrg s32p->pktcnt = (netbsd32_u_long)p->pktcnt;
373 1.2 mrg s32p->bytecnt = (netbsd32_u_long)p->bytecnt;
374 1.2 mrg s32p->wrong_if = (netbsd32_u_long)p->wrong_if;
375 1.1 mrg }
376 1.1 mrg
377 1.1 mrg
378 1.1 mrg /*
379 1.1 mrg * main ioctl syscall.
380 1.1 mrg *
381 1.1 mrg * ok, here we are in the biggy. we have to do fix ups depending
382 1.1 mrg * on the ioctl command before and afterwards.
383 1.1 mrg */
384 1.1 mrg int
385 1.4 eeh netbsd32_ioctl(p, v, retval)
386 1.1 mrg struct proc *p;
387 1.1 mrg void *v;
388 1.1 mrg register_t *retval;
389 1.1 mrg {
390 1.4 eeh struct netbsd32_ioctl_args /* {
391 1.1 mrg syscallarg(int) fd;
392 1.2 mrg syscallarg(netbsd32_u_long) com;
393 1.2 mrg syscallarg(netbsd32_voidp) data;
394 1.1 mrg } */ *uap = v;
395 1.5.4.1 mrg struct file *fp;
396 1.5.4.1 mrg struct filedesc *fdp;
397 1.5.4.1 mrg u_long com;
398 1.5.4.1 mrg int error = 0;
399 1.5.4.1 mrg u_int size, size32;
400 1.5.4.1 mrg caddr_t data, memp = NULL;
401 1.5.4.1 mrg caddr_t data32, memp32 = NULL;
402 1.5.4.1 mrg int tmp;
403 1.5.4.1 mrg #define STK_PARAMS 128
404 1.5.4.1 mrg u_long stkbuf[STK_PARAMS/sizeof(u_long)];
405 1.5.4.1 mrg u_long stkbuf32[STK_PARAMS/sizeof(u_long)];
406 1.1 mrg
407 1.1 mrg /*
408 1.1 mrg * we need to translate some commands (_IOW) before calling sys_ioctl,
409 1.1 mrg * some after (_IOR), and some both (_IOWR).
410 1.1 mrg */
411 1.5 eeh #if 0
412 1.5 eeh {
413 1.5 eeh char *dirs[8] = { "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!",
414 1.5 eeh "INOUT", "VOID|IN|OUT!" };
415 1.5 eeh
416 1.5 eeh printf("netbsd32_ioctl(%d, %x, %x): %s group %c base %d len %d\n",
417 1.5 eeh SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data),
418 1.5 eeh dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)],
419 1.5 eeh IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)),
420 1.5 eeh IOCPARM_LEN(SCARG(uap, com)));
421 1.5 eeh }
422 1.5 eeh #endif
423 1.1 mrg
424 1.5.4.1 mrg fdp = p->p_fd;
425 1.5.4.1 mrg if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
426 1.5.4.1 mrg (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
427 1.5.4.1 mrg (fp->f_iflags & FIF_WANTCLOSE) != 0)
428 1.5.4.1 mrg return (EBADF);
429 1.5.4.1 mrg
430 1.5.4.1 mrg FILE_USE(fp);
431 1.5.4.1 mrg
432 1.5.4.1 mrg if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
433 1.5.4.1 mrg error = EBADF;
434 1.5.4.1 mrg goto out;
435 1.5.4.1 mrg }
436 1.1 mrg
437 1.5.4.1 mrg switch (com = SCARG(uap, com)) {
438 1.5.4.1 mrg case FIONCLEX:
439 1.5.4.1 mrg fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
440 1.5.4.1 mrg goto out;
441 1.5.4.1 mrg
442 1.5.4.1 mrg case FIOCLEX:
443 1.5.4.1 mrg fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
444 1.5.4.1 mrg goto out;
445 1.1 mrg }
446 1.1 mrg
447 1.1 mrg /*
448 1.5.4.1 mrg * Interpret high order word to find amount of data to be
449 1.5.4.1 mrg * copied to/from the user's address space.
450 1.1 mrg */
451 1.5.4.1 mrg size32 = IOCPARM_LEN(com);
452 1.5.4.1 mrg if (size32 > IOCPARM_MAX) {
453 1.5.4.1 mrg error = ENOTTY;
454 1.5.4.1 mrg goto out;
455 1.5.4.1 mrg }
456 1.5.4.1 mrg memp = NULL;
457 1.5.4.1 mrg if (size32 > sizeof(stkbuf)) {
458 1.5.4.1 mrg memp32 = (caddr_t)malloc((u_long)size32, M_IOCTLOPS, M_WAITOK);
459 1.5.4.1 mrg data32 = memp32;
460 1.5.4.1 mrg } else
461 1.5.4.1 mrg data32 = (caddr_t)stkbuf32;
462 1.5.4.1 mrg if (com&IOC_IN) {
463 1.5.4.1 mrg if (size32) {
464 1.5.4.1 mrg error = copyin((caddr_t)(u_long)SCARG(uap, data),
465 1.5.4.1 mrg data32, size32);
466 1.5.4.1 mrg if (error) {
467 1.5.4.1 mrg if (memp32)
468 1.5.4.1 mrg free(memp32, M_IOCTLOPS);
469 1.5.4.1 mrg goto out;
470 1.5.4.1 mrg }
471 1.5.4.1 mrg } else
472 1.5.4.1 mrg *(caddr_t *)data32 = (caddr_t)(u_long)SCARG(uap, data);
473 1.5.4.1 mrg } else if ((com&IOC_OUT) && size32)
474 1.5.4.1 mrg /*
475 1.5.4.1 mrg * Zero the buffer so the user always
476 1.5.4.1 mrg * gets back something deterministic.
477 1.5.4.1 mrg */
478 1.5.4.1 mrg memset(data32, 0, size32);
479 1.5.4.1 mrg else if (com&IOC_VOID)
480 1.5.4.1 mrg *(caddr_t *)data = (caddr_t)(u_long)SCARG(uap, data);
481 1.1 mrg
482 1.5.4.1 mrg /* we define some handy macros here... */
483 1.5.4.1 mrg #define IOCTL_STRUCT_CONV_TO(cmd, type) \
484 1.5.4.1 mrg com = cmd; \
485 1.5.4.1 mrg size = IOCPARM_LEN(com); \
486 1.5.4.1 mrg if (size > sizeof(stkbuf)) \
487 1.5.4.1 mrg data = memp = malloc(size, M_IOCTLOPS, M_WAITOK); \
488 1.5.4.1 mrg else \
489 1.5.4.1 mrg data = (caddr_t)stkbuf; \
490 1.5.4.1 mrg __CONCAT(netbsd32_to_, type)((struct __CONCAT(netbsd32_, type) *) \
491 1.5.4.1 mrg data32, (struct type *)data, com); \
492 1.5.4.1 mrg error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); \
493 1.5.4.1 mrg __CONCAT(netbsd32_from_, type)((struct type *)data, \
494 1.5.4.1 mrg (struct __CONCAT(netbsd32_, type) *)data32); \
495 1.5.4.1 mrg break
496 1.1 mrg
497 1.1 mrg /*
498 1.5.4.1 mrg * convert various structures, pointers, and other objects that
499 1.5.4.1 mrg * change size from 32 bit -> 64 bit, for all ioctl commands.
500 1.1 mrg */
501 1.1 mrg switch (SCARG(uap, com)) {
502 1.5.4.1 mrg case FIONBIO:
503 1.5.4.1 mrg if ((tmp = *(int *)data) != 0)
504 1.5.4.1 mrg fp->f_flag |= FNONBLOCK;
505 1.5.4.1 mrg else
506 1.5.4.1 mrg fp->f_flag &= ~FNONBLOCK;
507 1.5.4.1 mrg error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
508 1.5.4.1 mrg break;
509 1.5.4.1 mrg
510 1.5.4.1 mrg case FIOASYNC:
511 1.5.4.1 mrg if ((tmp = *(int *)data) != 0)
512 1.5.4.1 mrg fp->f_flag |= FASYNC;
513 1.5.4.1 mrg else
514 1.5.4.1 mrg fp->f_flag &= ~FASYNC;
515 1.5.4.1 mrg error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
516 1.5.4.1 mrg break;
517 1.5.4.1 mrg
518 1.5.4.1 mrg case FIOSETOWN:
519 1.5.4.1 mrg tmp = *(int *)data;
520 1.5.4.1 mrg if (fp->f_type == DTYPE_SOCKET) {
521 1.5.4.1 mrg ((struct socket *)fp->f_data)->so_pgid = tmp;
522 1.5.4.1 mrg error = 0;
523 1.5.4.1 mrg break;
524 1.5.4.1 mrg }
525 1.5.4.1 mrg if (tmp <= 0) {
526 1.5.4.1 mrg tmp = -tmp;
527 1.5.4.1 mrg } else {
528 1.5.4.1 mrg struct proc *p1 = pfind(tmp);
529 1.5.4.1 mrg if (p1 == 0) {
530 1.5.4.1 mrg error = ESRCH;
531 1.5.4.1 mrg break;
532 1.5.4.1 mrg }
533 1.5.4.1 mrg tmp = p1->p_pgrp->pg_id;
534 1.5.4.1 mrg }
535 1.5.4.1 mrg error = (*fp->f_ops->fo_ioctl)
536 1.5.4.1 mrg (fp, TIOCSPGRP, (caddr_t)&tmp, p);
537 1.5.4.1 mrg break;
538 1.5.4.1 mrg
539 1.5.4.1 mrg case FIOGETOWN:
540 1.5.4.1 mrg if (fp->f_type == DTYPE_SOCKET) {
541 1.5.4.1 mrg error = 0;
542 1.5.4.1 mrg *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
543 1.5.4.1 mrg break;
544 1.5.4.1 mrg }
545 1.5.4.1 mrg error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
546 1.5.4.1 mrg *(int *)data = -*(int *)data;
547 1.1 mrg break;
548 1.1 mrg
549 1.5.4.1 mrg /*
550 1.5.4.1 mrg * Here are calls that need explicit conversion.
551 1.5.4.1 mrg */
552 1.5.4.1 mrg case FBIOPUTCMAP32:
553 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(FBIOPUTCMAP, fbcmap);
554 1.5.4.1 mrg case FBIOGETCMAP32:
555 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(FBIOGETCMAP, fbcmap);
556 1.5.4.1 mrg
557 1.5.4.1 mrg case FBIOSCURSOR32:
558 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(FBIOSCURSOR, fbcursor);
559 1.5.4.1 mrg case FBIOGCURSOR32:
560 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(FBIOGCURSOR, fbcursor);
561 1.5.4.1 mrg
562 1.5.4.1 mrg case OPIOCGET32:
563 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OPIOCGET, opiocdesc);
564 1.5.4.1 mrg case OPIOCSET32:
565 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OPIOCSET, opiocdesc);
566 1.5.4.1 mrg case OPIOCNEXTPROP32:
567 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OPIOCNEXTPROP, opiocdesc);
568 1.5.4.1 mrg
569 1.5.4.1 mrg case DIOCGPART32:
570 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo);
571 1.5.4.1 mrg
572 1.5.4.1 mrg case DIOCRFORMAT32:
573 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op);
574 1.5.4.1 mrg case DIOCWFORMAT32:
575 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(DIOCWFORMAT, format_op);
576 1.1 mrg
577 1.1 mrg /*
578 1.1 mrg * only a few ifreq syscalls need conversion and those are
579 1.1 mrg * all driver specific... XXX
580 1.1 mrg */
581 1.1 mrg #if 0
582 1.5.4.1 mrg case SIOCGADDRROM3232:
583 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGADDRROM32, ifreq);
584 1.5.4.1 mrg case SIOCGCHIPID32:
585 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGCHIPID, ifreq);
586 1.5.4.1 mrg case SIOCSIFADDR32:
587 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFADDR, ifreq);
588 1.5.4.1 mrg case OSIOCGIFADDR32:
589 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OSIOCGIFADDR, ifreq);
590 1.5.4.1 mrg case SIOCGIFADDR32:
591 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFADDR, ifreq);
592 1.5.4.1 mrg case SIOCSIFDSTADDR32:
593 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFDSTADDR, ifreq);
594 1.5.4.1 mrg case OSIOCGIFDSTADDR32:
595 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OSIOCGIFDSTADDR, ifreq);
596 1.5.4.1 mrg case SIOCGIFDSTADDR32:
597 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFDSTADDR, ifreq);
598 1.5.4.1 mrg case SIOCSIFFLAGS32:
599 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFFLAGS, ifreq);
600 1.5.4.1 mrg case SIOCGIFFLAGS32:
601 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFFLAGS, ifreq);
602 1.5.4.1 mrg case OSIOCGIFBRDADDR32:
603 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OSIOCGIFBRDADDR, ifreq);
604 1.5.4.1 mrg case SIOCGIFBRDADDR32:
605 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFBRDADDR, ifreq);
606 1.5.4.1 mrg case SIOCSIFBRDADDR32:
607 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFBRDADDR, ifreq);
608 1.5.4.1 mrg case OSIOCGIFNETMASK32:
609 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OSIOCGIFNETMASK, ifreq);
610 1.5.4.1 mrg case SIOCGIFNETMASK32:
611 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFNETMASK, ifreq);
612 1.5.4.1 mrg case SIOCSIFNETMASK32:
613 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFNETMASK, ifreq);
614 1.5.4.1 mrg case SIOCGIFMETRIC32:
615 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFMETRIC, ifreq);
616 1.5.4.1 mrg case SIOCSIFMETRIC32:
617 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFMETRIC, ifreq);
618 1.5.4.1 mrg case SIOCDIFADDR32:
619 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCDIFADDR, ifreq);
620 1.5.4.1 mrg case SIOCADDMULTI32:
621 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCADDMULTI, ifreq);
622 1.5.4.1 mrg case SIOCDELMULTI32:
623 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCDELMULTI, ifreq);
624 1.5.4.1 mrg case SIOCSIFMEDIA32:
625 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFMEDIA, ifreq);
626 1.5.4.1 mrg case SIOCSIFMTU32:
627 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFMTU, ifreq);
628 1.5.4.1 mrg case SIOCGIFMTU32:
629 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFMTU, ifreq);
630 1.5.4.1 mrg case SIOCSIFASYNCMAP32:
631 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSIFASYNCMAP, ifreq);
632 1.5.4.1 mrg case SIOCGIFASYNCMAP32:
633 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFASYNCMAP, ifreq);
634 1.5.4.1 mrg /* IOCTL_STRUCT_CONV_TO(BIOCGETIF, ifreq); READ ONLY */
635 1.5.4.1 mrg case BIOCSETIF32:
636 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(BIOCSETIF, ifreq);
637 1.5.4.1 mrg case SIOCPHASE132:
638 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCPHASE1, ifreq);
639 1.5.4.1 mrg case SIOCPHASE232:
640 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCPHASE2, ifreq);
641 1.1 mrg #endif
642 1.1 mrg
643 1.5.4.1 mrg case OSIOCGIFCONF32:
644 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(OSIOCGIFCONF, ifconf);
645 1.5.4.1 mrg case SIOCGIFCONF32:
646 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFCONF, ifconf);
647 1.1 mrg
648 1.5.4.1 mrg case SIOCGIFMEDIA32:
649 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq);
650 1.1 mrg
651 1.5.4.1 mrg case SIOCSDRVSPEC32:
652 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCSDRVSPEC, ifdrv);
653 1.1 mrg
654 1.5.4.1 mrg case SIOCGETVIFCNT32:
655 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGETVIFCNT, sioc_vif_req);
656 1.5.4.1 mrg
657 1.5.4.1 mrg case SIOCGETSGCNT32:
658 1.5.4.1 mrg IOCTL_STRUCT_CONV_TO(SIOCGETSGCNT, sioc_sg_req);
659 1.1 mrg
660 1.5.4.1 mrg default:
661 1.5.4.1 mrg error = (*fp->f_ops->fo_ioctl)(fp, com, data32, p);
662 1.1 mrg break;
663 1.1 mrg }
664 1.1 mrg
665 1.5.4.1 mrg /*
666 1.5.4.1 mrg * Copy any data to user, size was
667 1.5.4.1 mrg * already set and checked above.
668 1.5.4.1 mrg */
669 1.5.4.1 mrg if (error == 0 && (com&IOC_OUT) && size32)
670 1.5.4.1 mrg error = copyout(data32, (caddr_t)(u_long)SCARG(uap, data), size32);
671 1.1 mrg
672 1.5.4.1 mrg /* if we malloced data, free it here */
673 1.5.4.1 mrg if (memp32)
674 1.5.4.1 mrg free(memp32, M_IOCTLOPS);
675 1.5.4.1 mrg if (memp)
676 1.5.4.1 mrg free(memp, M_IOCTLOPS);
677 1.5.4.1 mrg
678 1.5.4.1 mrg out:
679 1.5.4.1 mrg FILE_UNUSE(fp, p);
680 1.5.4.1 mrg return (error);
681 1.1 mrg }
682