netbsd32_ioctl.c revision 1.6 1 1.6 mrg /* $NetBSD: netbsd32_ioctl.c,v 1.6 2000/07/09 13:39:31 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.1 mrg #include <sys/audioio.h>
38 1.1 mrg #include <sys/disklabel.h>
39 1.1 mrg #include <sys/dkio.h>
40 1.1 mrg #include <sys/malloc.h>
41 1.1 mrg #include <sys/proc.h>
42 1.1 mrg #include <sys/sockio.h>
43 1.1 mrg #include <sys/socket.h>
44 1.1 mrg #include <sys/ttycom.h>
45 1.1 mrg #include <sys/mount.h>
46 1.1 mrg #include <sys/syscallargs.h>
47 1.1 mrg
48 1.1 mrg #include <machine/fbio.h>
49 1.1 mrg #include <machine/openpromio.h>
50 1.1 mrg
51 1.1 mrg #include <net/if.h>
52 1.1 mrg #include <net/route.h>
53 1.1 mrg
54 1.1 mrg #include <netinet/in.h>
55 1.1 mrg #include <netinet/in_var.h>
56 1.1 mrg #include <netinet/igmp.h>
57 1.1 mrg #include <netinet/igmp_var.h>
58 1.1 mrg #include <netinet/ip_mroute.h>
59 1.1 mrg
60 1.2 mrg #include <compat/netbsd32/netbsd32.h>
61 1.2 mrg #include <compat/netbsd32/netbsd32_ioctl.h>
62 1.2 mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
63 1.1 mrg
64 1.6 mrg /* prototypes for the converters */
65 1.6 mrg static __inline void
66 1.6 mrg netbsd32_to_fbcmap(struct netbsd32_fbcmap *, struct fbcmap *);
67 1.6 mrg static __inline void
68 1.6 mrg netbsd32_to_fbcursor(struct netbsd32_fbcursor *, struct fbcursor *);
69 1.6 mrg static __inline void
70 1.6 mrg netbsd32_to_opiocdesc(struct netbsd32_opiocdesc *, struct opiocdesc *);
71 1.6 mrg static __inline void
72 1.6 mrg netbsd32_to_partinfo(struct netbsd32_partinfo *, struct partinfo *);
73 1.6 mrg static __inline void
74 1.6 mrg netbsd32_to_format_op(struct netbsd32_format_op *, struct format_op *);
75 1.6 mrg static __inline void
76 1.6 mrg netbsd32_to_ifconf(struct netbsd32_ifconf *, struct ifconf *);
77 1.6 mrg static __inline void
78 1.6 mrg netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *, struct ifmediareq *);
79 1.6 mrg static __inline void
80 1.6 mrg netbsd32_to_ifdrv(struct netbsd32_ifdrv *, struct ifdrv *);
81 1.6 mrg static __inline void
82 1.6 mrg netbsd32_to_sioc_vif_req(struct netbsd32_sioc_vif_req *, struct sioc_vif_req *);
83 1.6 mrg static __inline void
84 1.6 mrg netbsd32_to_sioc_sg_req(struct netbsd32_sioc_sg_req *, struct sioc_sg_req *);
85 1.6 mrg
86 1.6 mrg static __inline void
87 1.6 mrg netbsd32_from_fbcmap(struct fbcmap *, struct netbsd32_fbcmap *);
88 1.6 mrg static __inline void
89 1.6 mrg netbsd32_from_fbcursor(struct fbcursor *, struct netbsd32_fbcursor *);
90 1.6 mrg static __inline void
91 1.6 mrg netbsd32_from_opiocdesc(struct opiocdesc *, struct netbsd32_opiocdesc *);
92 1.6 mrg static __inline void
93 1.6 mrg netbsd32_from_format_op(struct format_op *, struct netbsd32_format_op *);
94 1.6 mrg static __inline void
95 1.6 mrg netbsd32_from_ifconf(struct ifconf *, struct netbsd32_ifconf *);
96 1.6 mrg static __inline void
97 1.6 mrg netbsd32_from_ifmediareq(struct ifmediareq *, struct netbsd32_ifmediareq *);
98 1.6 mrg static __inline void
99 1.6 mrg netbsd32_from_ifdrv(struct ifdrv *, struct netbsd32_ifdrv *);
100 1.6 mrg static __inline void
101 1.6 mrg netbsd32_from_sioc_vif_req(struct sioc_vif_req *, struct netbsd32_sioc_vif_req *);
102 1.6 mrg static __inline void
103 1.6 mrg netbsd32_from_sioc_sg_req(struct sioc_sg_req *, struct netbsd32_sioc_sg_req *);
104 1.6 mrg
105 1.6 mrg /* convert to/from different structures */
106 1.6 mrg
107 1.6 mrg static __inline void
108 1.2 mrg netbsd32_to_fbcmap(s32p, p)
109 1.2 mrg struct netbsd32_fbcmap *s32p;
110 1.1 mrg struct fbcmap *p;
111 1.1 mrg {
112 1.1 mrg
113 1.1 mrg p->index = s32p->index;
114 1.1 mrg p->count = s32p->count;
115 1.1 mrg p->red = (u_char *)(u_long)s32p->red;
116 1.1 mrg p->green = (u_char *)(u_long)s32p->green;
117 1.1 mrg p->blue = (u_char *)(u_long)s32p->blue;
118 1.1 mrg }
119 1.1 mrg
120 1.6 mrg static __inline void
121 1.2 mrg netbsd32_to_fbcursor(s32p, p)
122 1.2 mrg struct netbsd32_fbcursor *s32p;
123 1.1 mrg struct fbcursor *p;
124 1.1 mrg {
125 1.1 mrg
126 1.1 mrg p->set = s32p->set;
127 1.1 mrg p->enable = s32p->enable;
128 1.1 mrg p->pos = s32p->pos;
129 1.1 mrg p->hot = s32p->hot;
130 1.2 mrg netbsd32_to_fbcmap(&s32p->cmap, &p->cmap);
131 1.1 mrg p->size = s32p->size;
132 1.1 mrg p->image = (char *)(u_long)s32p->image;
133 1.1 mrg p->mask = (char *)(u_long)s32p->mask;
134 1.1 mrg }
135 1.1 mrg
136 1.6 mrg static __inline void
137 1.2 mrg netbsd32_to_opiocdesc(s32p, p)
138 1.2 mrg struct netbsd32_opiocdesc *s32p;
139 1.1 mrg struct opiocdesc *p;
140 1.1 mrg {
141 1.1 mrg
142 1.1 mrg p->op_nodeid = s32p->op_nodeid;
143 1.1 mrg p->op_namelen = s32p->op_namelen;
144 1.1 mrg p->op_name = (char *)(u_long)s32p->op_name;
145 1.1 mrg p->op_buflen = s32p->op_buflen;
146 1.1 mrg p->op_buf = (char *)(u_long)s32p->op_buf;
147 1.1 mrg }
148 1.1 mrg
149 1.6 mrg static __inline void
150 1.2 mrg netbsd32_to_partinfo(s32p, p)
151 1.2 mrg struct netbsd32_partinfo *s32p;
152 1.1 mrg struct partinfo *p;
153 1.1 mrg {
154 1.1 mrg
155 1.1 mrg p->disklab = (struct disklabel *)(u_long)s32p->disklab;
156 1.1 mrg p->part = (struct partition *)(u_long)s32p->part;
157 1.1 mrg }
158 1.1 mrg
159 1.6 mrg static __inline void
160 1.2 mrg netbsd32_to_format_op(s32p, p)
161 1.2 mrg struct netbsd32_format_op *s32p;
162 1.1 mrg struct format_op *p;
163 1.1 mrg {
164 1.1 mrg
165 1.1 mrg p->df_buf = (char *)(u_long)s32p->df_buf;
166 1.1 mrg p->df_count = s32p->df_count;
167 1.1 mrg p->df_startblk = s32p->df_startblk;
168 1.1 mrg memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg));
169 1.1 mrg }
170 1.1 mrg
171 1.1 mrg #if 0 /* XXX see below */
172 1.6 mrg static __inline void
173 1.2 mrg netbsd32_to_ifreq(s32p, p, cmd)
174 1.2 mrg struct netbsd32_ifreq *s32p;
175 1.1 mrg struct ifreq *p;
176 1.1 mrg u_long cmd; /* XXX unused yet */
177 1.1 mrg {
178 1.1 mrg
179 1.1 mrg /*
180 1.1 mrg * XXX
181 1.1 mrg * struct ifreq says the same, but sometimes the ifr_data
182 1.1 mrg * union member needs to be converted to 64 bits... this
183 1.1 mrg * is very driver specific and so we ignore it for now..
184 1.1 mrg */
185 1.1 mrg memcpy(p, s32p, sizeof *s32p);
186 1.1 mrg }
187 1.1 mrg #endif
188 1.1 mrg
189 1.6 mrg static __inline void
190 1.2 mrg netbsd32_to_ifconf(s32p, p)
191 1.2 mrg struct netbsd32_ifconf *s32p;
192 1.1 mrg struct ifconf *p;
193 1.1 mrg {
194 1.1 mrg
195 1.1 mrg p->ifc_len = s32p->ifc_len;
196 1.1 mrg /* ifc_buf & ifc_req are the same size so this works */
197 1.1 mrg p->ifc_buf = (caddr_t)(u_long)s32p->ifc_buf;
198 1.1 mrg }
199 1.1 mrg
200 1.6 mrg static __inline void
201 1.2 mrg netbsd32_to_ifmediareq(s32p, p)
202 1.2 mrg struct netbsd32_ifmediareq *s32p;
203 1.1 mrg struct ifmediareq *p;
204 1.1 mrg {
205 1.1 mrg
206 1.1 mrg memcpy(p, s32p, sizeof *s32p);
207 1.1 mrg p->ifm_ulist = (int *)(u_long)s32p->ifm_ulist;
208 1.1 mrg }
209 1.1 mrg
210 1.6 mrg static __inline void
211 1.2 mrg netbsd32_to_ifdrv(s32p, p)
212 1.2 mrg struct netbsd32_ifdrv *s32p;
213 1.1 mrg struct ifdrv *p;
214 1.1 mrg {
215 1.1 mrg
216 1.1 mrg memcpy(p, s32p, sizeof *s32p);
217 1.1 mrg p->ifd_data = (void *)(u_long)s32p->ifd_data;
218 1.1 mrg }
219 1.1 mrg
220 1.6 mrg static __inline void
221 1.2 mrg netbsd32_to_sioc_vif_req(s32p, p)
222 1.2 mrg struct netbsd32_sioc_vif_req *s32p;
223 1.1 mrg struct sioc_vif_req *p;
224 1.1 mrg {
225 1.1 mrg
226 1.1 mrg p->vifi = s32p->vifi;
227 1.1 mrg p->icount = (u_long)s32p->icount;
228 1.1 mrg p->ocount = (u_long)s32p->ocount;
229 1.1 mrg p->ibytes = (u_long)s32p->ibytes;
230 1.1 mrg p->obytes = (u_long)s32p->obytes;
231 1.1 mrg }
232 1.1 mrg
233 1.6 mrg static __inline void
234 1.2 mrg netbsd32_to_sioc_sg_req(s32p, p)
235 1.2 mrg struct netbsd32_sioc_sg_req *s32p;
236 1.1 mrg struct sioc_sg_req *p;
237 1.1 mrg {
238 1.1 mrg
239 1.1 mrg p->src = s32p->src;
240 1.1 mrg p->grp = s32p->grp;
241 1.1 mrg p->pktcnt = (u_long)s32p->pktcnt;
242 1.1 mrg p->bytecnt = (u_long)s32p->bytecnt;
243 1.1 mrg p->wrong_if = (u_long)s32p->wrong_if;
244 1.1 mrg }
245 1.1 mrg
246 1.1 mrg /*
247 1.2 mrg * handle ioctl conversions from sparc64 -> netbsd32
248 1.1 mrg */
249 1.1 mrg
250 1.6 mrg static __inline void
251 1.2 mrg netbsd32_from_fbcmap(p, s32p)
252 1.1 mrg struct fbcmap *p;
253 1.2 mrg struct netbsd32_fbcmap *s32p;
254 1.1 mrg {
255 1.1 mrg
256 1.1 mrg s32p->index = p->index;
257 1.1 mrg s32p->count = p->count;
258 1.1 mrg /* filled in */
259 1.1 mrg #if 0
260 1.2 mrg s32p->red = (netbsd32_u_charp)p->red;
261 1.2 mrg s32p->green = (netbsd32_u_charp)p->green;
262 1.2 mrg s32p->blue = (netbsd32_u_charp)p->blue;
263 1.1 mrg #endif
264 1.1 mrg }
265 1.1 mrg
266 1.6 mrg static __inline void
267 1.2 mrg netbsd32_from_fbcursor(p, s32p)
268 1.1 mrg struct fbcursor *p;
269 1.2 mrg struct netbsd32_fbcursor *s32p;
270 1.1 mrg {
271 1.1 mrg
272 1.1 mrg s32p->set = p->set;
273 1.1 mrg s32p->enable = p->enable;
274 1.1 mrg s32p->pos = p->pos;
275 1.1 mrg s32p->hot = p->hot;
276 1.2 mrg netbsd32_from_fbcmap(&p->cmap, &s32p->cmap);
277 1.1 mrg s32p->size = p->size;
278 1.1 mrg /* filled in */
279 1.1 mrg #if 0
280 1.2 mrg s32p->image = (netbsd32_charp)p->image;
281 1.2 mrg s32p->mask = (netbsd32_charp)p->mask;
282 1.1 mrg #endif
283 1.1 mrg }
284 1.1 mrg
285 1.6 mrg static __inline void
286 1.2 mrg netbsd32_from_opiocdesc(p, s32p)
287 1.1 mrg struct opiocdesc *p;
288 1.2 mrg struct netbsd32_opiocdesc *s32p;
289 1.1 mrg {
290 1.1 mrg
291 1.1 mrg s32p->op_nodeid = p->op_nodeid;
292 1.1 mrg s32p->op_namelen = p->op_namelen;
293 1.2 mrg s32p->op_name = (netbsd32_charp)(u_long)p->op_name;
294 1.1 mrg s32p->op_buflen = p->op_buflen;
295 1.2 mrg s32p->op_buf = (netbsd32_charp)(u_long)p->op_buf;
296 1.1 mrg }
297 1.1 mrg
298 1.6 mrg static __inline void
299 1.2 mrg netbsd32_from_format_op(p, s32p)
300 1.1 mrg struct format_op *p;
301 1.2 mrg struct netbsd32_format_op *s32p;
302 1.1 mrg {
303 1.1 mrg
304 1.1 mrg /* filled in */
305 1.1 mrg #if 0
306 1.2 mrg s32p->df_buf = (netbsd32_charp)p->df_buf;
307 1.1 mrg #endif
308 1.1 mrg s32p->df_count = p->df_count;
309 1.1 mrg s32p->df_startblk = p->df_startblk;
310 1.1 mrg memcpy(s32p->df_reg, p->df_reg, sizeof(p->df_reg));
311 1.1 mrg }
312 1.1 mrg
313 1.1 mrg #if 0 /* XXX see below */
314 1.6 mrg static __inline void
315 1.2 mrg netbsd32_from_ifreq(p, s32p, cmd)
316 1.1 mrg struct ifreq *p;
317 1.2 mrg struct netbsd32_ifreq *s32p;
318 1.1 mrg u_long cmd; /* XXX unused yet */
319 1.1 mrg {
320 1.1 mrg
321 1.1 mrg /*
322 1.1 mrg * XXX
323 1.1 mrg * struct ifreq says the same, but sometimes the ifr_data
324 1.1 mrg * union member needs to be converted to 64 bits... this
325 1.1 mrg * is very driver specific and so we ignore it for now..
326 1.1 mrg */
327 1.1 mrg *s32p = *p;
328 1.1 mrg }
329 1.1 mrg #endif
330 1.1 mrg
331 1.6 mrg static __inline void
332 1.2 mrg netbsd32_from_ifconf(p, s32p)
333 1.1 mrg struct ifconf *p;
334 1.2 mrg struct netbsd32_ifconf *s32p;
335 1.1 mrg {
336 1.1 mrg
337 1.1 mrg s32p->ifc_len = p->ifc_len;
338 1.1 mrg /* ifc_buf & ifc_req are the same size so this works */
339 1.2 mrg s32p->ifc_buf = (netbsd32_caddr_t)(u_long)p->ifc_buf;
340 1.1 mrg }
341 1.1 mrg
342 1.6 mrg static __inline void
343 1.2 mrg netbsd32_from_ifmediareq(p, s32p)
344 1.1 mrg struct ifmediareq *p;
345 1.2 mrg struct netbsd32_ifmediareq *s32p;
346 1.1 mrg {
347 1.1 mrg
348 1.1 mrg memcpy(s32p, p, sizeof *p);
349 1.1 mrg /* filled in? */
350 1.1 mrg #if 0
351 1.2 mrg s32p->ifm_ulist = (netbsd32_intp_t)p->ifm_ulist;
352 1.1 mrg #endif
353 1.1 mrg }
354 1.1 mrg
355 1.6 mrg static __inline void
356 1.2 mrg netbsd32_from_ifdrv(p, s32p)
357 1.1 mrg struct ifdrv *p;
358 1.2 mrg struct netbsd32_ifdrv *s32p;
359 1.1 mrg {
360 1.1 mrg
361 1.1 mrg memcpy(s32p, p, sizeof *p);
362 1.1 mrg /* filled in? */
363 1.1 mrg #if 0
364 1.2 mrg s32p->ifm_data = (netbsd32_u_longp_t)p->ifm_data;
365 1.1 mrg #endif
366 1.1 mrg }
367 1.1 mrg
368 1.6 mrg static __inline void
369 1.2 mrg netbsd32_from_sioc_vif_req(p, s32p)
370 1.1 mrg struct sioc_vif_req *p;
371 1.2 mrg struct netbsd32_sioc_vif_req *s32p;
372 1.1 mrg {
373 1.1 mrg
374 1.1 mrg s32p->vifi = p->vifi;
375 1.2 mrg s32p->icount = (netbsd32_u_long)p->icount;
376 1.2 mrg s32p->ocount = (netbsd32_u_long)p->ocount;
377 1.2 mrg s32p->ibytes = (netbsd32_u_long)p->ibytes;
378 1.2 mrg s32p->obytes = (netbsd32_u_long)p->obytes;
379 1.1 mrg }
380 1.1 mrg
381 1.6 mrg static __inline void
382 1.2 mrg netbsd32_from_sioc_sg_req(p, s32p)
383 1.1 mrg struct sioc_sg_req *p;
384 1.2 mrg struct netbsd32_sioc_sg_req *s32p;
385 1.1 mrg {
386 1.1 mrg
387 1.1 mrg s32p->src = p->src;
388 1.1 mrg s32p->grp = p->grp;
389 1.2 mrg s32p->pktcnt = (netbsd32_u_long)p->pktcnt;
390 1.2 mrg s32p->bytecnt = (netbsd32_u_long)p->bytecnt;
391 1.2 mrg s32p->wrong_if = (netbsd32_u_long)p->wrong_if;
392 1.1 mrg }
393 1.1 mrg
394 1.1 mrg
395 1.1 mrg /*
396 1.1 mrg * main ioctl syscall.
397 1.1 mrg *
398 1.1 mrg * ok, here we are in the biggy. we have to do fix ups depending
399 1.1 mrg * on the ioctl command before and afterwards.
400 1.1 mrg */
401 1.1 mrg int
402 1.4 eeh netbsd32_ioctl(p, v, retval)
403 1.1 mrg struct proc *p;
404 1.1 mrg void *v;
405 1.1 mrg register_t *retval;
406 1.1 mrg {
407 1.4 eeh struct netbsd32_ioctl_args /* {
408 1.1 mrg syscallarg(int) fd;
409 1.2 mrg syscallarg(netbsd32_u_long) com;
410 1.2 mrg syscallarg(netbsd32_voidp) data;
411 1.1 mrg } */ *uap = v;
412 1.1 mrg struct sys_ioctl_args ua;
413 1.1 mrg void *data = NULL;
414 1.1 mrg int rv;
415 1.1 mrg
416 1.1 mrg /*
417 1.1 mrg * we need to translate some commands (_IOW) before calling sys_ioctl,
418 1.1 mrg * some after (_IOR), and some both (_IOWR).
419 1.1 mrg */
420 1.5 eeh #if 0
421 1.5 eeh {
422 1.5 eeh char *dirs[8] = { "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!",
423 1.5 eeh "INOUT", "VOID|IN|OUT!" };
424 1.5 eeh
425 1.5 eeh printf("netbsd32_ioctl(%d, %x, %x): %s group %c base %d len %d\n",
426 1.5 eeh SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data),
427 1.5 eeh dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)],
428 1.5 eeh IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)),
429 1.5 eeh IOCPARM_LEN(SCARG(uap, com)));
430 1.5 eeh }
431 1.5 eeh #endif
432 1.1 mrg
433 1.1 mrg /* we define some handy macros here... */
434 1.1 mrg #define IOCTL_STRUCT_CONV_TO(type) \
435 1.1 mrg data = malloc(sizeof(struct type), M_TEMP, M_WAITOK); \
436 1.2 mrg __CONCAT(netbsd32_to_, type)((struct __CONCAT(netbsd32_, type) *) \
437 1.1 mrg (u_long)SCARG(uap, data), data)
438 1.1 mrg
439 1.1 mrg #define IOCTL_STRUCT_CONV_CMD_TO(type, cmd) \
440 1.1 mrg data = malloc(sizeof(struct type), M_TEMP, M_WAITOK); \
441 1.2 mrg __CONCAT(netbsd32_to_, type)((struct __CONCAT(netbsd32_, type) *) \
442 1.1 mrg (u_long)SCARG(uap, data), data, cmd)
443 1.1 mrg
444 1.1 mrg #define IOCTL_STRUCT_CONV_FROM(type) \
445 1.2 mrg __CONCAT(netbsd32_from_, type)(data, \
446 1.2 mrg (struct __CONCAT(netbsd32_, type) *) (u_long)SCARG(uap, data))
447 1.1 mrg
448 1.1 mrg #define IOCTL_STRUCT_CONV_CMD_FROM(type, cmd) \
449 1.2 mrg __CONCAT(netbsd32_from_, type)(data, \
450 1.2 mrg (struct __CONCAT(netbsd32_, type) *) (u_long)SCARG(uap, data), cmd)
451 1.1 mrg
452 1.1 mrg /*
453 1.1 mrg * convert various structures, pointers, and other objects that
454 1.1 mrg * change size from 32 bit -> 64 bit, for all ioctl commands.
455 1.1 mrg */
456 1.1 mrg switch (SCARG(uap, com)) {
457 1.1 mrg case FBIOPUTCMAP:
458 1.1 mrg case FBIOGETCMAP:
459 1.1 mrg IOCTL_STRUCT_CONV_TO(fbcmap);
460 1.1 mrg break;
461 1.1 mrg
462 1.1 mrg case FBIOSCURSOR:
463 1.1 mrg case FBIOGCURSOR:
464 1.1 mrg IOCTL_STRUCT_CONV_TO(fbcursor);
465 1.1 mrg break;
466 1.1 mrg
467 1.1 mrg case OPIOCGET:
468 1.1 mrg case OPIOCSET:
469 1.1 mrg case OPIOCNEXTPROP:
470 1.1 mrg IOCTL_STRUCT_CONV_TO(opiocdesc);
471 1.1 mrg break;
472 1.1 mrg
473 1.1 mrg case DIOCGPART:
474 1.1 mrg IOCTL_STRUCT_CONV_TO(partinfo);
475 1.1 mrg break;
476 1.1 mrg
477 1.1 mrg case DIOCRFORMAT:
478 1.1 mrg case DIOCWFORMAT:
479 1.1 mrg IOCTL_STRUCT_CONV_TO(format_op);
480 1.1 mrg break;
481 1.1 mrg
482 1.1 mrg /*
483 1.1 mrg * only a few ifreq syscalls need conversion and those are
484 1.1 mrg * all driver specific... XXX
485 1.1 mrg */
486 1.1 mrg #if 0
487 1.1 mrg case SIOCGADDRROM:
488 1.1 mrg case SIOCGCHIPID:
489 1.1 mrg case SIOCSIFADDR:
490 1.1 mrg case OSIOCGIFADDR:
491 1.1 mrg case SIOCGIFADDR:
492 1.1 mrg case SIOCSIFDSTADDR:
493 1.1 mrg case OSIOCGIFDSTADDR:
494 1.1 mrg case SIOCGIFDSTADDR:
495 1.1 mrg case SIOCSIFFLAGS:
496 1.1 mrg case SIOCGIFFLAGS:
497 1.1 mrg case OSIOCGIFBRDADDR:
498 1.1 mrg case SIOCGIFBRDADDR:
499 1.1 mrg case SIOCSIFBRDADDR:
500 1.1 mrg case OSIOCGIFNETMASK:
501 1.1 mrg case SIOCGIFNETMASK:
502 1.1 mrg case SIOCSIFNETMASK:
503 1.1 mrg case SIOCGIFMETRIC:
504 1.1 mrg case SIOCSIFMETRIC:
505 1.1 mrg case SIOCDIFADDR:
506 1.1 mrg case SIOCADDMULTI:
507 1.1 mrg case SIOCDELMULTI:
508 1.1 mrg case SIOCSIFMEDIA:
509 1.1 mrg case SIOCSIFMTU:
510 1.1 mrg case SIOCGIFMTU:
511 1.1 mrg case SIOCSIFASYNCMAP:
512 1.1 mrg case SIOCGIFASYNCMAP:
513 1.1 mrg /* case BIOCGETIF: READ ONLY */
514 1.1 mrg case BIOCSETIF:
515 1.1 mrg case SIOCPHASE1:
516 1.1 mrg case SIOCPHASE2:
517 1.1 mrg IOCTL_STRUCT_CONV_CMD_TO(ifreq, SCARG(uap, cmd));
518 1.1 mrg break;
519 1.1 mrg #endif
520 1.1 mrg
521 1.1 mrg case OSIOCGIFCONF:
522 1.1 mrg case SIOCGIFCONF:
523 1.1 mrg IOCTL_STRUCT_CONV_TO(ifconf);
524 1.1 mrg break;
525 1.1 mrg
526 1.1 mrg case SIOCGIFMEDIA:
527 1.1 mrg IOCTL_STRUCT_CONV_TO(ifmediareq);
528 1.1 mrg break;
529 1.1 mrg
530 1.1 mrg case SIOCSDRVSPEC:
531 1.1 mrg IOCTL_STRUCT_CONV_TO(ifdrv);
532 1.1 mrg break;
533 1.1 mrg
534 1.1 mrg case SIOCGETVIFCNT:
535 1.1 mrg IOCTL_STRUCT_CONV_TO(sioc_vif_req);
536 1.1 mrg break;
537 1.1 mrg
538 1.1 mrg case SIOCGETSGCNT:
539 1.1 mrg IOCTL_STRUCT_CONV_TO(sioc_sg_req);
540 1.1 mrg break;
541 1.1 mrg
542 1.1 mrg }
543 1.1 mrg
544 1.1 mrg /*
545 1.1 mrg * if we malloced a new data segment, plug it into the
546 1.1 mrg * syscall args, otherwise copy incoming one as a void
547 1.1 mrg * pointer. also copy the rest of the syscall args...
548 1.1 mrg */
549 1.1 mrg if (data)
550 1.1 mrg SCARG(&ua, data) = data;
551 1.1 mrg else
552 1.3 mrg NETBSD32TOP_UAP(data, void);
553 1.3 mrg NETBSD32TO64_UAP(fd);
554 1.3 mrg NETBSD32TOX_UAP(com, u_long);
555 1.1 mrg
556 1.1 mrg /* call the real ioctl */
557 1.1 mrg rv = sys_ioctl(p, &ua, retval);
558 1.1 mrg
559 1.1 mrg /*
560 1.1 mrg * convert _back_ to 32 bit the results of the command.
561 1.1 mrg */
562 1.1 mrg switch (SCARG(uap, com)) {
563 1.1 mrg case FBIOGETCMAP:
564 1.1 mrg IOCTL_STRUCT_CONV_FROM(fbcmap);
565 1.1 mrg break;
566 1.1 mrg
567 1.1 mrg case FBIOGCURSOR:
568 1.1 mrg IOCTL_STRUCT_CONV_FROM(fbcursor);
569 1.1 mrg break;
570 1.1 mrg
571 1.1 mrg case OPIOCGET:
572 1.1 mrg case OPIOCNEXTPROP:
573 1.1 mrg IOCTL_STRUCT_CONV_FROM(opiocdesc);
574 1.1 mrg break;
575 1.1 mrg
576 1.1 mrg case DIOCRFORMAT:
577 1.1 mrg case DIOCWFORMAT:
578 1.1 mrg IOCTL_STRUCT_CONV_FROM(format_op);
579 1.1 mrg break;
580 1.1 mrg
581 1.1 mrg /*
582 1.1 mrg * only a few ifreq syscalls need conversion and those are
583 1.1 mrg * all driver specific... XXX
584 1.1 mrg */
585 1.1 mrg #if 0
586 1.1 mrg case SIOCGADDRROM:
587 1.1 mrg case SIOCGCHIPID:
588 1.1 mrg case SIOCSIFADDR:
589 1.1 mrg case OSIOCGIFADDR:
590 1.1 mrg case SIOCGIFADDR:
591 1.1 mrg case SIOCSIFDSTADDR:
592 1.1 mrg case OSIOCGIFDSTADDR:
593 1.1 mrg case SIOCGIFDSTADDR:
594 1.1 mrg case SIOCSIFFLAGS:
595 1.1 mrg case SIOCGIFFLAGS:
596 1.1 mrg case OSIOCGIFBRDADDR:
597 1.1 mrg case SIOCGIFBRDADDR:
598 1.1 mrg case SIOCSIFBRDADDR:
599 1.1 mrg case OSIOCGIFNETMASK:
600 1.1 mrg case SIOCGIFNETMASK:
601 1.1 mrg case SIOCSIFNETMASK:
602 1.1 mrg case SIOCGIFMETRIC:
603 1.1 mrg case SIOCSIFMETRIC:
604 1.1 mrg case SIOCDIFADDR:
605 1.1 mrg case SIOCADDMULTI:
606 1.1 mrg case SIOCDELMULTI:
607 1.1 mrg case SIOCSIFMEDIA:
608 1.1 mrg case SIOCSIFMTU:
609 1.1 mrg case SIOCGIFMTU:
610 1.1 mrg case SIOCSIFASYNCMAP:
611 1.1 mrg case SIOCGIFASYNCMAP:
612 1.1 mrg /* case BIOCGETIF: READ ONLY */
613 1.1 mrg case BIOCSETIF:
614 1.1 mrg case SIOCPHASE1:
615 1.1 mrg case SIOCPHASE2:
616 1.1 mrg IOCTL_STRUCT_CONV_CMD_FROM(ifreq, SCARG(uap, cmd));
617 1.1 mrg break;
618 1.1 mrg #endif
619 1.1 mrg
620 1.1 mrg case OSIOCGIFCONF:
621 1.1 mrg case SIOCGIFCONF:
622 1.1 mrg IOCTL_STRUCT_CONV_FROM(ifconf);
623 1.1 mrg break;
624 1.1 mrg
625 1.1 mrg case SIOCGIFMEDIA:
626 1.1 mrg IOCTL_STRUCT_CONV_FROM(ifmediareq);
627 1.1 mrg break;
628 1.1 mrg
629 1.1 mrg case SIOCSDRVSPEC:
630 1.1 mrg IOCTL_STRUCT_CONV_FROM(ifdrv);
631 1.1 mrg break;
632 1.1 mrg
633 1.1 mrg case SIOCGETVIFCNT:
634 1.1 mrg IOCTL_STRUCT_CONV_FROM(sioc_vif_req);
635 1.1 mrg break;
636 1.1 mrg
637 1.1 mrg case SIOCGETSGCNT:
638 1.1 mrg IOCTL_STRUCT_CONV_FROM(sioc_sg_req);
639 1.1 mrg break;
640 1.1 mrg }
641 1.1 mrg
642 1.1 mrg /* if we malloced data, free it here */
643 1.1 mrg if (data)
644 1.1 mrg free(data, M_TEMP);
645 1.1 mrg
646 1.1 mrg /* done! */
647 1.1 mrg return (rv);
648 1.1 mrg }
649