2 * Copyright (c) 1994-1995 Søren Schmidt
3 * Copyright (c) 2004 Simon 'corecode' Schubert
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer
11 * in this position and unchanged.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software withough specific prior written permission
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * $FreeBSD: src/sys/compat/linux/linux_ioctl.c,v 1.55.2.11 2003/05/01 20:16:09 anholt Exp $
30 * $DragonFly: src/sys/emulation/linux/linux_ioctl.c,v 1.25 2008/03/07 11:34:19 sephe Exp $
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/sysproto.h>
37 #include <sys/consio.h>
38 #include <sys/ctype.h>
39 #include <sys/diskslice.h>
40 #include <sys/fcntl.h>
42 #include <sys/filedesc.h>
43 #include <sys/filio.h>
45 #include <sys/kernel.h>
46 #include <sys/linker_set.h>
47 #include <sys/malloc.h>
48 #include <sys/mapped_ioctl.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52 #include <sys/soundcard.h>
56 #include <net/if_dl.h>
57 #include <net/if_types.h>
59 #include <sys/file2.h>
60 #include <sys/mplock2.h>
62 #include <arch_linux/linux.h>
63 #include <arch_linux/linux_proto.h>
65 #include "linux_ioctl.h"
66 #include "linux_mib.h"
67 #include "linux_util.h"
71 linux_ioctl_BLKGETSIZE32(struct file
*fp
, u_long cmd
, u_long ocmd
,
72 caddr_t data
, struct ucred
*cred
)
74 struct partinfo dpart
;
78 error
= fo_ioctl(fp
, DIOCGPART
, (caddr_t
)&dpart
, cred
, NULL
);
81 value
= dpart
.media_blocks
; /* 64->32 */
82 bcopy(&value
, data
, sizeof(value
));
88 * termio related ioctls
92 unsigned short c_iflag
;
93 unsigned short c_oflag
;
94 unsigned short c_cflag
;
95 unsigned short c_lflag
;
97 unsigned char c_cc
[LINUX_NCC
];
100 struct linux_termios
{
101 unsigned int c_iflag
;
102 unsigned int c_oflag
;
103 unsigned int c_cflag
;
104 unsigned int c_lflag
;
105 unsigned char c_line
;
106 unsigned char c_cc
[LINUX_NCCS
];
109 struct linux_winsize
{
110 unsigned short ws_row
, ws_col
;
111 unsigned short ws_xpixel
, ws_ypixel
;
114 static struct speedtab sptab
[] = {
115 { B0
, LINUX_B0
}, { B50
, LINUX_B50
},
116 { B75
, LINUX_B75
}, { B110
, LINUX_B110
},
117 { B134
, LINUX_B134
}, { B150
, LINUX_B150
},
118 { B200
, LINUX_B200
}, { B300
, LINUX_B300
},
119 { B600
, LINUX_B600
}, { B1200
, LINUX_B1200
},
120 { B1800
, LINUX_B1800
}, { B2400
, LINUX_B2400
},
121 { B4800
, LINUX_B4800
}, { B9600
, LINUX_B9600
},
122 { B19200
, LINUX_B19200
}, { B38400
, LINUX_B38400
},
123 { B57600
, LINUX_B57600
}, { B115200
, LINUX_B115200
},
127 struct linux_serial_struct
{
136 unsigned short close_delay
;
137 char reserved_char
[2];
139 unsigned short closing_wait
;
140 unsigned short closing_wait2
;
145 linux_to_bsd_speed(int code
, struct speedtab
*table
)
147 for ( ; table
->sp_code
!= -1; table
++)
148 if (table
->sp_code
== code
)
149 return (table
->sp_speed
);
154 bsd_to_linux_speed(int speed
, struct speedtab
*table
)
156 for ( ; table
->sp_speed
!= -1; table
++)
157 if (table
->sp_speed
== speed
)
158 return (table
->sp_code
);
163 bsd_to_linux_termios(struct termios
*bios
, struct linux_termios
*lios
)
169 kprintf("LINUX: BSD termios structure (input):\n");
170 kprintf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
171 bios
->c_iflag
, bios
->c_oflag
, bios
->c_cflag
, bios
->c_lflag
,
172 bios
->c_ispeed
, bios
->c_ospeed
);
174 for (i
=0; i
<NCCS
; i
++)
175 kprintf("%02x ", bios
->c_cc
[i
]);
181 if (bios
->c_iflag
& IGNBRK
)
182 lios
->c_iflag
|= LINUX_IGNBRK
;
183 if (bios
->c_iflag
& BRKINT
)
184 lios
->c_iflag
|= LINUX_BRKINT
;
185 if (bios
->c_iflag
& IGNPAR
)
186 lios
->c_iflag
|= LINUX_IGNPAR
;
187 if (bios
->c_iflag
& PARMRK
)
188 lios
->c_iflag
|= LINUX_PARMRK
;
189 if (bios
->c_iflag
& INPCK
)
190 lios
->c_iflag
|= LINUX_INPCK
;
191 if (bios
->c_iflag
& ISTRIP
)
192 lios
->c_iflag
|= LINUX_ISTRIP
;
193 if (bios
->c_iflag
& INLCR
)
194 lios
->c_iflag
|= LINUX_INLCR
;
195 if (bios
->c_iflag
& IGNCR
)
196 lios
->c_iflag
|= LINUX_IGNCR
;
197 if (bios
->c_iflag
& ICRNL
)
198 lios
->c_iflag
|= LINUX_ICRNL
;
199 if (bios
->c_iflag
& IXON
)
200 lios
->c_iflag
|= LINUX_IXON
;
201 if (bios
->c_iflag
& IXANY
)
202 lios
->c_iflag
|= LINUX_IXANY
;
203 if (bios
->c_iflag
& IXOFF
)
204 lios
->c_iflag
|= LINUX_IXOFF
;
205 if (bios
->c_iflag
& IMAXBEL
)
206 lios
->c_iflag
|= LINUX_IMAXBEL
;
209 if (bios
->c_oflag
& OPOST
)
210 lios
->c_oflag
|= LINUX_OPOST
;
211 if (bios
->c_oflag
& ONLCR
)
212 lios
->c_oflag
|= LINUX_ONLCR
;
213 if (bios
->c_oflag
& OXTABS
)
214 lios
->c_oflag
|= LINUX_XTABS
;
216 lios
->c_cflag
= bsd_to_linux_speed(bios
->c_ispeed
, sptab
);
217 lios
->c_cflag
|= (bios
->c_cflag
& CSIZE
) >> 4;
218 if (bios
->c_cflag
& CSTOPB
)
219 lios
->c_cflag
|= LINUX_CSTOPB
;
220 if (bios
->c_cflag
& CREAD
)
221 lios
->c_cflag
|= LINUX_CREAD
;
222 if (bios
->c_cflag
& PARENB
)
223 lios
->c_cflag
|= LINUX_PARENB
;
224 if (bios
->c_cflag
& PARODD
)
225 lios
->c_cflag
|= LINUX_PARODD
;
226 if (bios
->c_cflag
& HUPCL
)
227 lios
->c_cflag
|= LINUX_HUPCL
;
228 if (bios
->c_cflag
& CLOCAL
)
229 lios
->c_cflag
|= LINUX_CLOCAL
;
230 if (bios
->c_cflag
& CRTSCTS
)
231 lios
->c_cflag
|= LINUX_CRTSCTS
;
234 if (bios
->c_lflag
& ISIG
)
235 lios
->c_lflag
|= LINUX_ISIG
;
236 if (bios
->c_lflag
& ICANON
)
237 lios
->c_lflag
|= LINUX_ICANON
;
238 if (bios
->c_lflag
& ECHO
)
239 lios
->c_lflag
|= LINUX_ECHO
;
240 if (bios
->c_lflag
& ECHOE
)
241 lios
->c_lflag
|= LINUX_ECHOE
;
242 if (bios
->c_lflag
& ECHOK
)
243 lios
->c_lflag
|= LINUX_ECHOK
;
244 if (bios
->c_lflag
& ECHONL
)
245 lios
->c_lflag
|= LINUX_ECHONL
;
246 if (bios
->c_lflag
& NOFLSH
)
247 lios
->c_lflag
|= LINUX_NOFLSH
;
248 if (bios
->c_lflag
& TOSTOP
)
249 lios
->c_lflag
|= LINUX_TOSTOP
;
250 if (bios
->c_lflag
& ECHOCTL
)
251 lios
->c_lflag
|= LINUX_ECHOCTL
;
252 if (bios
->c_lflag
& ECHOPRT
)
253 lios
->c_lflag
|= LINUX_ECHOPRT
;
254 if (bios
->c_lflag
& ECHOKE
)
255 lios
->c_lflag
|= LINUX_ECHOKE
;
256 if (bios
->c_lflag
& FLUSHO
)
257 lios
->c_lflag
|= LINUX_FLUSHO
;
258 if (bios
->c_lflag
& PENDIN
)
259 lios
->c_lflag
|= LINUX_PENDIN
;
260 if (bios
->c_lflag
& IEXTEN
)
261 lios
->c_lflag
|= LINUX_IEXTEN
;
263 for (i
=0; i
<LINUX_NCCS
; i
++)
264 lios
->c_cc
[i
] = LINUX_POSIX_VDISABLE
;
265 lios
->c_cc
[LINUX_VINTR
] = bios
->c_cc
[VINTR
];
266 lios
->c_cc
[LINUX_VQUIT
] = bios
->c_cc
[VQUIT
];
267 lios
->c_cc
[LINUX_VERASE
] = bios
->c_cc
[VERASE
];
268 lios
->c_cc
[LINUX_VKILL
] = bios
->c_cc
[VKILL
];
269 lios
->c_cc
[LINUX_VEOF
] = bios
->c_cc
[VEOF
];
270 lios
->c_cc
[LINUX_VEOL
] = bios
->c_cc
[VEOL
];
271 lios
->c_cc
[LINUX_VMIN
] = bios
->c_cc
[VMIN
];
272 lios
->c_cc
[LINUX_VTIME
] = bios
->c_cc
[VTIME
];
273 lios
->c_cc
[LINUX_VEOL2
] = bios
->c_cc
[VEOL2
];
274 lios
->c_cc
[LINUX_VSUSP
] = bios
->c_cc
[VSUSP
];
275 lios
->c_cc
[LINUX_VSTART
] = bios
->c_cc
[VSTART
];
276 lios
->c_cc
[LINUX_VSTOP
] = bios
->c_cc
[VSTOP
];
277 lios
->c_cc
[LINUX_VREPRINT
] = bios
->c_cc
[VREPRINT
];
278 lios
->c_cc
[LINUX_VDISCARD
] = bios
->c_cc
[VDISCARD
];
279 lios
->c_cc
[LINUX_VWERASE
] = bios
->c_cc
[VWERASE
];
280 lios
->c_cc
[LINUX_VLNEXT
] = bios
->c_cc
[VLNEXT
];
282 for (i
=0; i
<LINUX_NCCS
; i
++) {
283 if (i
!= LINUX_VMIN
&& i
!= LINUX_VTIME
&&
284 lios
->c_cc
[i
] == _POSIX_VDISABLE
)
285 lios
->c_cc
[i
] = LINUX_POSIX_VDISABLE
;
291 kprintf("LINUX: LINUX termios structure (output):\n");
292 kprintf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
293 lios
->c_iflag
, lios
->c_oflag
, lios
->c_cflag
,
294 lios
->c_lflag
, (int)lios
->c_line
);
296 for (i
=0; i
<LINUX_NCCS
; i
++)
297 kprintf("%02x ", lios
->c_cc
[i
]);
304 linux_to_bsd_termios(struct linux_termios
*lios
, struct termios
*bios
)
310 kprintf("LINUX: LINUX termios structure (input):\n");
311 kprintf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
312 lios
->c_iflag
, lios
->c_oflag
, lios
->c_cflag
,
313 lios
->c_lflag
, (int)lios
->c_line
);
315 for (i
=0; i
<LINUX_NCCS
; i
++)
316 kprintf("%02x ", lios
->c_cc
[i
]);
322 if (lios
->c_iflag
& LINUX_IGNBRK
)
323 bios
->c_iflag
|= IGNBRK
;
324 if (lios
->c_iflag
& LINUX_BRKINT
)
325 bios
->c_iflag
|= BRKINT
;
326 if (lios
->c_iflag
& LINUX_IGNPAR
)
327 bios
->c_iflag
|= IGNPAR
;
328 if (lios
->c_iflag
& LINUX_PARMRK
)
329 bios
->c_iflag
|= PARMRK
;
330 if (lios
->c_iflag
& LINUX_INPCK
)
331 bios
->c_iflag
|= INPCK
;
332 if (lios
->c_iflag
& LINUX_ISTRIP
)
333 bios
->c_iflag
|= ISTRIP
;
334 if (lios
->c_iflag
& LINUX_INLCR
)
335 bios
->c_iflag
|= INLCR
;
336 if (lios
->c_iflag
& LINUX_IGNCR
)
337 bios
->c_iflag
|= IGNCR
;
338 if (lios
->c_iflag
& LINUX_ICRNL
)
339 bios
->c_iflag
|= ICRNL
;
340 if (lios
->c_iflag
& LINUX_IXON
)
341 bios
->c_iflag
|= IXON
;
342 if (lios
->c_iflag
& LINUX_IXANY
)
343 bios
->c_iflag
|= IXANY
;
344 if (lios
->c_iflag
& LINUX_IXOFF
)
345 bios
->c_iflag
|= IXOFF
;
346 if (lios
->c_iflag
& LINUX_IMAXBEL
)
347 bios
->c_iflag
|= IMAXBEL
;
350 if (lios
->c_oflag
& LINUX_OPOST
)
351 bios
->c_oflag
|= OPOST
;
352 if (lios
->c_oflag
& LINUX_ONLCR
)
353 bios
->c_oflag
|= ONLCR
;
354 if (lios
->c_oflag
& LINUX_XTABS
)
355 bios
->c_oflag
|= OXTABS
;
357 bios
->c_cflag
= (lios
->c_cflag
& LINUX_CSIZE
) << 4;
358 if (lios
->c_cflag
& LINUX_CSTOPB
)
359 bios
->c_cflag
|= CSTOPB
;
360 if (lios
->c_cflag
& LINUX_CREAD
)
361 bios
->c_cflag
|= CREAD
;
362 if (lios
->c_cflag
& LINUX_PARENB
)
363 bios
->c_cflag
|= PARENB
;
364 if (lios
->c_cflag
& LINUX_PARODD
)
365 bios
->c_cflag
|= PARODD
;
366 if (lios
->c_cflag
& LINUX_HUPCL
)
367 bios
->c_cflag
|= HUPCL
;
368 if (lios
->c_cflag
& LINUX_CLOCAL
)
369 bios
->c_cflag
|= CLOCAL
;
370 if (lios
->c_cflag
& LINUX_CRTSCTS
)
371 bios
->c_cflag
|= CRTSCTS
;
374 if (lios
->c_lflag
& LINUX_ISIG
)
375 bios
->c_lflag
|= ISIG
;
376 if (lios
->c_lflag
& LINUX_ICANON
)
377 bios
->c_lflag
|= ICANON
;
378 if (lios
->c_lflag
& LINUX_ECHO
)
379 bios
->c_lflag
|= ECHO
;
380 if (lios
->c_lflag
& LINUX_ECHOE
)
381 bios
->c_lflag
|= ECHOE
;
382 if (lios
->c_lflag
& LINUX_ECHOK
)
383 bios
->c_lflag
|= ECHOK
;
384 if (lios
->c_lflag
& LINUX_ECHONL
)
385 bios
->c_lflag
|= ECHONL
;
386 if (lios
->c_lflag
& LINUX_NOFLSH
)
387 bios
->c_lflag
|= NOFLSH
;
388 if (lios
->c_lflag
& LINUX_TOSTOP
)
389 bios
->c_lflag
|= TOSTOP
;
390 if (lios
->c_lflag
& LINUX_ECHOCTL
)
391 bios
->c_lflag
|= ECHOCTL
;
392 if (lios
->c_lflag
& LINUX_ECHOPRT
)
393 bios
->c_lflag
|= ECHOPRT
;
394 if (lios
->c_lflag
& LINUX_ECHOKE
)
395 bios
->c_lflag
|= ECHOKE
;
396 if (lios
->c_lflag
& LINUX_FLUSHO
)
397 bios
->c_lflag
|= FLUSHO
;
398 if (lios
->c_lflag
& LINUX_PENDIN
)
399 bios
->c_lflag
|= PENDIN
;
400 if (lios
->c_lflag
& LINUX_IEXTEN
)
401 bios
->c_lflag
|= IEXTEN
;
403 for (i
=0; i
<NCCS
; i
++)
404 bios
->c_cc
[i
] = _POSIX_VDISABLE
;
405 bios
->c_cc
[VINTR
] = lios
->c_cc
[LINUX_VINTR
];
406 bios
->c_cc
[VQUIT
] = lios
->c_cc
[LINUX_VQUIT
];
407 bios
->c_cc
[VERASE
] = lios
->c_cc
[LINUX_VERASE
];
408 bios
->c_cc
[VKILL
] = lios
->c_cc
[LINUX_VKILL
];
409 bios
->c_cc
[VEOF
] = lios
->c_cc
[LINUX_VEOF
];
410 bios
->c_cc
[VEOL
] = lios
->c_cc
[LINUX_VEOL
];
411 bios
->c_cc
[VMIN
] = lios
->c_cc
[LINUX_VMIN
];
412 bios
->c_cc
[VTIME
] = lios
->c_cc
[LINUX_VTIME
];
413 bios
->c_cc
[VEOL2
] = lios
->c_cc
[LINUX_VEOL2
];
414 bios
->c_cc
[VSUSP
] = lios
->c_cc
[LINUX_VSUSP
];
415 bios
->c_cc
[VSTART
] = lios
->c_cc
[LINUX_VSTART
];
416 bios
->c_cc
[VSTOP
] = lios
->c_cc
[LINUX_VSTOP
];
417 bios
->c_cc
[VREPRINT
] = lios
->c_cc
[LINUX_VREPRINT
];
418 bios
->c_cc
[VDISCARD
] = lios
->c_cc
[LINUX_VDISCARD
];
419 bios
->c_cc
[VWERASE
] = lios
->c_cc
[LINUX_VWERASE
];
420 bios
->c_cc
[VLNEXT
] = lios
->c_cc
[LINUX_VLNEXT
];
422 for (i
=0; i
<NCCS
; i
++) {
423 if (i
!= VMIN
&& i
!= VTIME
&&
424 bios
->c_cc
[i
] == LINUX_POSIX_VDISABLE
)
425 bios
->c_cc
[i
] = _POSIX_VDISABLE
;
428 bios
->c_ispeed
= bios
->c_ospeed
=
429 linux_to_bsd_speed(lios
->c_cflag
& LINUX_CBAUD
, sptab
);
433 kprintf("LINUX: BSD termios structure (output):\n");
434 kprintf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
435 bios
->c_iflag
, bios
->c_oflag
, bios
->c_cflag
, bios
->c_lflag
,
436 bios
->c_ispeed
, bios
->c_ospeed
);
438 for (i
=0; i
<NCCS
; i
++)
439 kprintf("%02x ", bios
->c_cc
[i
]);
446 bsd_to_linux_termio(struct termios
*bios
, struct linux_termio
*lio
)
448 struct linux_termios lios
;
450 bsd_to_linux_termios(bios
, &lios
);
451 lio
->c_iflag
= lios
.c_iflag
;
452 lio
->c_oflag
= lios
.c_oflag
;
453 lio
->c_cflag
= lios
.c_cflag
;
454 lio
->c_lflag
= lios
.c_lflag
;
455 lio
->c_line
= lios
.c_line
;
456 memcpy(lio
->c_cc
, lios
.c_cc
, LINUX_NCC
);
460 linux_to_bsd_termio(struct linux_termio
*lio
, struct termios
*bios
)
462 struct linux_termios lios
;
465 lios
.c_iflag
= lio
->c_iflag
;
466 lios
.c_oflag
= lio
->c_oflag
;
467 lios
.c_cflag
= lio
->c_cflag
;
468 lios
.c_lflag
= lio
->c_lflag
;
469 for (i
=LINUX_NCC
; i
<LINUX_NCCS
; i
++)
470 lios
.c_cc
[i
] = LINUX_POSIX_VDISABLE
;
471 memcpy(lios
.c_cc
, lio
->c_cc
, LINUX_NCC
);
472 linux_to_bsd_termios(&lios
, bios
);
476 linux_ioctl_TCGETS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
479 struct linux_termios lios
;
482 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
, NULL
);
485 bsd_to_linux_termios(&bios
, &lios
);
486 bcopy(&lios
, data
, sizeof(lios
));
491 linux_ioctl_TCSETS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
494 struct linux_termios lios
;
496 bcopy(data
, &lios
, sizeof(lios
));
497 linux_to_bsd_termios(&lios
, &bios
);
498 return (fo_ioctl(fp
, TIOCSETA
, (caddr_t
)&bios
, cred
, NULL
));
502 linux_ioctl_TCSETSW(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
505 struct linux_termios lios
;
507 bcopy(data
, &lios
, sizeof(lios
));
508 linux_to_bsd_termios(&lios
, &bios
);
509 return (fo_ioctl(fp
, TIOCSETAW
, (caddr_t
)&bios
, cred
, NULL
));
513 linux_ioctl_TCSETSF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
516 struct linux_termios lios
;
518 bcopy(data
, &lios
, sizeof(lios
));
519 linux_to_bsd_termios(&lios
, &bios
);
520 return (fo_ioctl(fp
, TIOCSETAF
, (caddr_t
)&bios
, cred
, NULL
));
524 linux_ioctl_TCGETA(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
527 struct linux_termio lio
;
530 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
, NULL
);
533 bsd_to_linux_termio(&bios
, &lio
);
534 bcopy(&lio
, data
, sizeof(lio
));
539 linux_ioctl_TCSETA(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
542 struct linux_termio lio
;
544 bcopy(data
, &lio
, sizeof(lio
));
545 linux_to_bsd_termio(&lio
, &bios
);
546 return (fo_ioctl(fp
, TIOCSETA
, (caddr_t
)&bios
, cred
, NULL
));
550 linux_ioctl_TCSETAW(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
553 struct linux_termio lio
;
555 bcopy(data
, &lio
, sizeof(lio
));
556 linux_to_bsd_termio(&lio
, &bios
);
557 return (fo_ioctl(fp
, TIOCSETAW
, (caddr_t
)&bios
, cred
, NULL
));
561 linux_ioctl_TCSETAF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
564 struct linux_termio lio
;
566 bcopy(data
, &lio
, sizeof(lio
));
567 linux_to_bsd_termio(&lio
, &bios
);
568 return (fo_ioctl(fp
, TIOCSETAF
, (caddr_t
)&bios
, cred
, NULL
));
572 linux_ioctl_TIOCLINUX(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
574 switch ((u_char
)*data
) {
575 case 11: /* LINUX_TIOCLINUX_KERNMSG */
578 kprintf("Unknown LINUX_TIOCLINUX: %d\n", ((u_char
)*data
));
579 kprintf("cmd = %lu, ocmd = %lu\n", cmd
, ocmd
);
586 linux_ioctl_TCXONC(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
588 switch ((u_long
)data
) {
600 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
, NULL
);
603 c
= ((u_long
)data
== LINUX_TCIOFF
) ? VSTOP
: VSTART
;
605 if (c
!= _POSIX_VDISABLE
) {
609 aiov
.iov_base
= (char *)&c
;
610 aiov
.iov_len
= sizeof(*bios
.c_cc
);
611 auio
.uio_iov
= &aiov
;
613 auio
.uio_offset
= -1;
614 auio
.uio_resid
= sizeof(*bios
.c_cc
);
615 auio
.uio_rw
= UIO_WRITE
;
616 auio
.uio_segflg
= UIO_SYSSPACE
;
617 auio
.uio_td
= curthread
;
619 return (fo_write(fp
, &auio
, fp
->f_cred
, 0));
627 return (fo_ioctl(fp
, cmd
, 0, cred
, NULL
));
631 linux_ioctl_TCFLSH(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
633 switch ((u_long
)data
) {
635 *(u_long
*)data
= FREAD
;
638 *(u_long
*)data
= FWRITE
;
640 case LINUX_TCIOFLUSH
:
641 *(u_long
*)data
= FREAD
| FWRITE
;
646 return (fo_ioctl(fp
, TIOCFLUSH
, data
, cred
, NULL
));
650 linux_ioctl_TIOCGSERIAL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
652 struct linux_serial_struct lss
;
654 lss
.type
= LINUX_PORT_16550A
;
657 bcopy(&lss
, data
, sizeof(lss
));
662 linux_ioctl_TIOCSSERIAL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
665 struct linux_serial_struct lss
;
667 bcopy(data
, &lss
, sizeof(lss
));
668 /* XXX - It really helps to have an implementation that
676 linux_ioctl_TIOCSETD(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
680 switch ((u_long
)data
) {
693 return (fo_ioctl(fp
, TIOCSETD
, (caddr_t
)&line
, cred
, NULL
));
697 linux_ioctl_TIOCGETD(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
699 int linux_line
, error
;
700 int bsd_line
= TTYDISC
;
702 error
= fo_ioctl(fp
, TIOCGETD
, (caddr_t
)&bsd_line
, cred
, NULL
);
707 linux_line
= LINUX_N_TTY
;
710 linux_line
= LINUX_N_SLIP
;
713 linux_line
= LINUX_N_PPP
;
718 bcopy(&linux_line
, data
, sizeof(int));
724 * CDROM related ioctls
727 struct linux_cdrom_msf
737 struct linux_cdrom_tochdr
743 union linux_cdrom_addr
753 struct linux_cdrom_tocentry
759 union linux_cdrom_addr cdte_addr
;
760 u_char cdte_datamode
;
763 struct linux_cdrom_subchnl
766 u_char cdsc_audiostatus
;
771 union linux_cdrom_addr cdsc_absaddr
;
772 union linux_cdrom_addr cdsc_reladdr
;
776 bsd_to_linux_msf_lba(u_char af
, union msf_lba
*bp
, union linux_cdrom_addr
*lp
)
778 if (af
== CD_LBA_FORMAT
)
781 lp
->msf
.minute
= bp
->msf
.minute
;
782 lp
->msf
.second
= bp
->msf
.second
;
783 lp
->msf
.frame
= bp
->msf
.frame
;
788 set_linux_cdrom_addr(union linux_cdrom_addr
*addr
, int format
, int lba
)
790 if (format
== LINUX_CDROM_MSF
) {
791 addr
->msf
.frame
= lba
% 75;
794 addr
->msf
.second
= lba
% 60;
795 addr
->msf
.minute
= lba
/ 60;
801 linux_ioctl_CDROMREADTOCHDR(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
803 struct ioc_toc_header th
;
804 struct linux_cdrom_tochdr lth
;
807 error
= fo_ioctl(fp
, CDIOREADTOCHEADER
, (caddr_t
)&th
, cred
, NULL
);
810 lth
.cdth_trk0
= th
.starting_track
;
811 lth
.cdth_trk1
= th
.ending_track
;
812 bcopy(<h
, data
, sizeof(lth
));
817 linux_ioctl_CDROMREADTOCENTRY(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
819 struct linux_cdrom_tocentry
*ltep
= (struct linux_cdrom_tocentry
*)data
;
820 struct ioc_read_toc_single_entry irtse
;
823 irtse
.address_format
= ltep
->cdte_format
;
824 irtse
.track
= ltep
->cdte_track
;
825 error
= fo_ioctl(fp
, CDIOREADTOCENTRY
, (caddr_t
)&irtse
, cred
, NULL
);
829 ltep
->cdte_ctrl
= irtse
.entry
.control
;
830 ltep
->cdte_adr
= irtse
.entry
.addr_type
;
831 bsd_to_linux_msf_lba(irtse
.address_format
, &irtse
.entry
.addr
,
837 linux_ioctl_CDROMSUBCHNL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
839 struct linux_cdrom_subchnl
*sc
= (struct linux_cdrom_subchnl
*)data
;
840 struct ioc_read_subchannel bsdsc
;
841 struct cd_sub_channel_info
*bsdinfo
;
843 caddr_t sg
= stackgap_init();
845 bsdinfo
= stackgap_alloc(&sg
, sizeof(struct cd_sub_channel_info
));
846 bsdsc
.address_format
= CD_LBA_FORMAT
;
847 bsdsc
.data_format
= CD_CURRENT_POSITION
;
849 bsdsc
.data_len
= sizeof(struct cd_sub_channel_info
);
850 bsdsc
.data
= bsdinfo
;
851 error
= fo_ioctl(fp
, CDIOCREADSUBCHANNEL
, (caddr_t
)&bsdsc
, cred
, NULL
);
854 sc
->cdsc_audiostatus
= bsdinfo
->header
.audio_status
;
855 sc
->cdsc_adr
= bsdinfo
->what
.position
.addr_type
;
856 sc
->cdsc_ctrl
= bsdinfo
->what
.position
.control
;
857 sc
->cdsc_trk
= bsdinfo
->what
.position
.track_number
;
858 sc
->cdsc_ind
= bsdinfo
->what
.position
.index_number
;
859 set_linux_cdrom_addr(&sc
->cdsc_absaddr
, sc
->cdsc_format
, bsdinfo
->what
.position
.absaddr
.lba
);
860 set_linux_cdrom_addr(&sc
->cdsc_reladdr
, sc
->cdsc_format
, bsdinfo
->what
.position
.reladdr
.lba
);
866 * Sound related ioctls
870 linux_ioctl_OSS_GETVERSION(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
872 int version
= linux_get_oss_version(curthread
);
874 bcopy(&version
, data
, sizeof(int));
880 * Console related ioctls
883 #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
886 linux_ioctl_KDSKBMODE(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
890 switch ((u_long
)data
) {
894 case LINUX_KBD_XLATE
:
897 case LINUX_KBD_MEDIUMRAW
:
903 return (fo_ioctl(fp
, KDSKBMODE
, (caddr_t
)&kbdmode
, cred
, NULL
));
907 linux_ioctl_VT_SETMODE(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
909 struct vt_mode
*mode
= (struct vt_mode
*)data
;
911 if (!ISSIGVALID(mode
->frsig
) && ISSIGVALID(mode
->acqsig
))
912 mode
->frsig
= mode
->acqsig
;
913 return (fo_ioctl(fp
, VT_SETMODE
, data
, cred
, NULL
));
918 * Socket related ioctls
922 * Criteria for interface name translation
924 #define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
927 * Interface function used by linprocfs (at the time of writing). It's not
928 * used by the Linuxulator itself.
931 linux_ifname(struct ifnet
*ifp
, char *buffer
, size_t buflen
)
933 struct ifnet
*ifscan
;
936 /* Short-circuit non ethernet interfaces */
937 if (!IFP_IS_ETH(ifp
))
938 return (strlcpy(buffer
, ifp
->if_xname
, buflen
));
940 /* Determine the (relative) unit number for ethernet interfaces */
942 TAILQ_FOREACH(ifscan
, &ifnet
, if_link
) {
944 return (ksnprintf(buffer
, buflen
, "eth%d", ethno
));
945 if (IFP_IS_ETH(ifscan
))
953 * Translate a Linux interface name to a FreeBSD interface name,
954 * and return the associated ifnet structure
955 * bsdname and lxname need to be least IFNAMSIZ bytes long, but
956 * can point to the same buffer.
959 static struct ifnet
*
960 ifname_linux_to_bsd(const char *lxname
, char *bsdname
)
967 for (len
= 0; len
< LINUX_IFNAMSIZ
; ++len
)
968 if (!isalpha(lxname
[len
]))
970 if (len
== 0 || len
== LINUX_IFNAMSIZ
)
972 unit
= (int)strtoul(lxname
+ len
, &ep
, 10);
973 if (ep
== NULL
|| ep
== lxname
+ len
|| ep
>= lxname
+ LINUX_IFNAMSIZ
)
976 is_eth
= (len
== 3 && !strncmp(lxname
, "eth", len
)) ? 1 : 0;
977 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
979 * Allow Linux programs to use FreeBSD names. Don't presume
980 * we never have an interface named "eth", so don't make
981 * the test optional based on is_eth.
983 if (strncmp(ifp
->if_xname
, lxname
, LINUX_IFNAMSIZ
) == 0)
985 if (is_eth
&& IFP_IS_ETH(ifp
) && unit
== index
++)
989 strlcpy(bsdname
, ifp
->if_xname
, IFNAMSIZ
);
994 linux_ioctl_SIOCGIFCONF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
996 struct ifconf
*ifc
= (struct ifconf
*)data
;
1003 /* much easier to use uiomove than keep track ourselves */
1004 iov
.iov_base
= ifc
->ifc_buf
;
1005 iov
.iov_len
= ifc
->ifc_len
;
1009 uio
.uio_resid
= ifc
->ifc_len
;
1010 uio
.uio_segflg
= UIO_USERSPACE
;
1011 uio
.uio_rw
= UIO_READ
;
1012 uio
.uio_td
= curthread
;
1014 /* Keep track of eth interfaces */
1017 /* Return all AF_INET addresses of all interfaces */
1018 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
1019 struct ifaddr_container
*ifac
;
1021 if (uio
.uio_resid
<= 0)
1024 bzero(&ifr
, sizeof ifr
);
1025 if (IFP_IS_ETH(ifp
))
1026 ksnprintf(ifr
.ifr_name
, LINUX_IFNAMSIZ
, "eth%d",
1029 strlcpy(ifr
.ifr_name
, ifp
->if_xname
, LINUX_IFNAMSIZ
);
1031 /* Walk the address list */
1032 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1033 struct ifaddr
*ifa
= ifac
->ifa
;
1034 struct sockaddr
*sa
= ifa
->ifa_addr
;
1036 if (uio
.uio_resid
<= 0)
1039 if (sa
->sa_family
== AF_INET
) {
1040 ifr
.ifr_addr
.sa_family
= LINUX_AF_INET
;
1041 memcpy(ifr
.ifr_addr
.sa_data
, sa
->sa_data
,
1042 sizeof(ifr
.ifr_addr
.sa_data
));
1044 error
= uiomove((caddr_t
)&ifr
, sizeof ifr
,
1052 ifc
->ifc_len
-= uio
.uio_resid
;
1058 linux_ioctl_SIOCGIFFLAGS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1060 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1062 char ifname
[IFNAMSIZ
];
1066 if (fp
->f_type
!= DTYPE_SOCKET
) {
1067 /* XXX: I doubt this is correct because
1068 * we don't translate the ifname and
1069 * use l_ifreq instead of ifreq
1071 return (fo_ioctl(fp
, SIOCGIFFLAGS
, data
, cred
, NULL
));
1075 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1079 flags
= ifp
->if_flags
;
1080 /* these flags have no Linux equivalent */
1081 flags
&= ~(IFF_SMART
|IFF_OACTIVE
|IFF_SIMPLEX
|
1082 IFF_LINK0
|IFF_LINK1
|IFF_LINK2
);
1083 /* Linux' multicast flag is in a different bit */
1084 if (flags
& IFF_MULTICAST
) {
1085 flags
&= ~IFF_MULTICAST
;
1089 ifr
->ifr_flags
= flags
;
1093 #define ARPHRD_ETHER 1
1094 #define ARPHRD_LOOPBACK 772
1096 /* XXX: could implement using native ioctl, so only mapping */
1098 linux_ioctl_SIOCGIFINDEX(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1100 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1102 char ifname
[IFNAMSIZ
];
1105 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1110 kprintf("Interface index: %d\n", ifp
->if_index
);
1113 index
= ifp
->if_index
;
1114 return (copyout(&index
, &ifr
->ifr_ifindex
, sizeof(index
)));
1118 linux_ioctl_SIOCGIFMETRIC(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1120 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1122 char ifname
[IFNAMSIZ
];
1125 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1130 kprintf("Interface metric: %d\n", ifp
->if_metric
);
1133 metric
= ifp
->if_metric
;
1134 return (copyout(&metric
, &ifr
->ifr_ifmetric
, sizeof(metric
)));
1138 linux_ioctl_SIOGIFHWADDR(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1140 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1142 char ifname
[IFNAMSIZ
];
1143 struct sockaddr_dl
*sdl
;
1144 struct l_sockaddr lsa
;
1145 struct ifaddr_container
*ifac
;
1147 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1152 if (ifp
->if_type
== IFT_LOOP
) {
1153 bzero(&ifr
->ifr_hwaddr
, sizeof lsa
);
1154 ifr
->ifr_hwaddr
.sa_family
= ARPHRD_LOOPBACK
;
1158 if (ifp
->if_type
!= IFT_ETHER
)
1161 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1162 struct ifaddr
*ifa
= ifac
->ifa
;
1164 sdl
= (struct sockaddr_dl
*)ifa
->ifa_addr
;
1165 if (sdl
!= NULL
&& (sdl
->sdl_family
== AF_LINK
) &&
1166 (sdl
->sdl_type
== IFT_ETHER
)) {
1167 bzero(&ifr
->ifr_hwaddr
, sizeof lsa
);
1168 ifr
->ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
1169 bcopy(LLADDR(sdl
), ifr
->ifr_hwaddr
.sa_data
, LINUX_IFHWADDRLEN
);
1178 linux_ioctl_map_ifname(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1182 char *oifname
= (char *)data
;
1183 char lifname
[LINUX_IFNAMSIZ
];
1185 KASSERT(LINUX_IFNAMSIZ
== IFNAMSIZ
,
1186 ("%s(): LINUX_IFNAMSIZ != IFNAMSIZ", __func__
));
1188 if (fp
->f_type
!= DTYPE_SOCKET
) {
1190 * XXX: I doubt this is correct because
1191 * we don't map the ifname
1193 /* not a socket - probably a tap / vmnet device */
1194 if (ocmd
== LINUX_SIOCGIFADDR
|| ocmd
== LINUX_SIOCSIFADDR
) {
1195 cmd
= (ocmd
== LINUX_SIOCGIFADDR
) ? SIOCGIFADDR
: SIOCSIFADDR
;
1196 return (fo_ioctl(fp
, cmd
, data
, cred
, NULL
));
1201 /* Save the original ifname */
1202 bcopy(oifname
, lifname
, LINUX_IFNAMSIZ
);
1204 kprintf("%s(): ioctl %d on %.*s\n", __func__
,
1205 (int)(cmd
& 0xffff), LINUX_IFNAMSIZ
, lifname
);
1207 /* Replace linux ifname with bsd ifname */
1208 ifp
= ifname_linux_to_bsd(lifname
, oifname
);
1215 kprintf("%s(): %s translated to %s\n", __func__
,
1219 error
= fo_ioctl(fp
, cmd
, data
, cred
, NULL
);
1222 bcopy(lifname
, oifname
, LINUX_IFNAMSIZ
);
1228 * generic linux -> BSD syscall direction mapper
1231 linux_gen_dirmap(u_long lstart
, u_long lend
, u_long bstart
, u_long bend
, u_long cmd
, u_long ocmd
)
1233 static u_int32_t dirbits
[4] = { IOC_VOID
, IOC_IN
, IOC_OUT
, IOC_INOUT
};
1235 return ((cmd
& ~IOC_DIRMASK
) | dirbits
[ocmd
>> 30]);
1239 static struct ioctl_map_range linux_ioctl_map_entries
[] = {
1241 MAPPED_IOCTL_IOR(LINUX_BLKGETSIZE
, linux_ioctl_BLKGETSIZE32
, uint32_t),
1243 MAPPED_IOCTL_IOR(LINUX_TCGETS
, linux_ioctl_TCGETS
, struct linux_termios
),
1244 MAPPED_IOCTL_IOW(LINUX_TCSETS
, linux_ioctl_TCSETS
, struct linux_termios
),
1245 MAPPED_IOCTL_IOW(LINUX_TCSETSW
, linux_ioctl_TCSETSW
, struct linux_termios
),
1246 MAPPED_IOCTL_IOW(LINUX_TCSETSF
, linux_ioctl_TCSETSF
, struct linux_termios
),
1247 MAPPED_IOCTL_IOR(LINUX_TCGETA
, linux_ioctl_TCGETA
, struct linux_termio
),
1248 MAPPED_IOCTL_IOW(LINUX_TCSETA
, linux_ioctl_TCSETA
, struct linux_termio
),
1249 MAPPED_IOCTL_IOW(LINUX_TCSETAW
, linux_ioctl_TCSETAW
, struct linux_termio
),
1250 MAPPED_IOCTL_IOW(LINUX_TCSETAF
, linux_ioctl_TCSETAF
, struct linux_termio
),
1251 MAPPED_IOCTL_IO(LINUX_TCXONC
, linux_ioctl_TCXONC
),
1252 MAPPED_IOCTL_IO(LINUX_TCFLSH
, linux_ioctl_TCFLSH
),
1253 MAPPED_IOCTL_IO(LINUX_TIOCLINUX
, linux_ioctl_TIOCLINUX
),
1254 MAPPED_IOCTL_MAP(LINUX_TIOCEXCL
, TIOCEXCL
),
1255 MAPPED_IOCTL_MAP(LINUX_TIOCNXCL
, TIOCNXCL
),
1256 MAPPED_IOCTL_MAP(LINUX_TIOCGPGRP
, TIOCGPGRP
),
1257 MAPPED_IOCTL_MAP(LINUX_TIOCSPGRP
, TIOCSPGRP
),
1258 MAPPED_IOCTL_MAP(LINUX_TIOCGWINSZ
, TIOCGWINSZ
),
1259 MAPPED_IOCTL_MAP(LINUX_TIOCSWINSZ
, TIOCSWINSZ
),
1260 MAPPED_IOCTL_MAP(LINUX_TIOCMGET
, TIOCMGET
),
1261 MAPPED_IOCTL_MAP(LINUX_TIOCMBIS
, TIOCMBIS
),
1262 MAPPED_IOCTL_MAP(LINUX_TIOCMBIC
, TIOCMBIC
),
1263 MAPPED_IOCTL_MAP(LINUX_TIOCMSET
, TIOCMSET
),
1264 MAPPED_IOCTL_MAP(LINUX_FIONREAD
, FIONREAD
),
1265 MAPPED_IOCTL_MAP(LINUX_TIOCCONS
, TIOCCONS
),
1266 MAPPED_IOCTL_IOR(LINUX_TIOCGSERIAL
, linux_ioctl_TIOCGSERIAL
, struct linux_serial_struct
),
1267 MAPPED_IOCTL_IOW(LINUX_TIOCSSERIAL
, linux_ioctl_TIOCSSERIAL
, struct linux_serial_struct
),
1268 MAPPED_IOCTL_MAP(LINUX_FIONBIO
, FIONBIO
),
1269 MAPPED_IOCTL_MAP(LINUX_TIOCNOTTY
, TIOCNOTTY
),
1270 MAPPED_IOCTL_IO(LINUX_TIOCSETD
, linux_ioctl_TIOCSETD
),
1271 MAPPED_IOCTL_IOR(LINUX_TIOCGETD
, linux_ioctl_TIOCGETD
, int),
1272 MAPPED_IOCTL_MAP(LINUX_FIONCLEX
, FIONCLEX
),
1273 MAPPED_IOCTL_MAP(LINUX_FIOCLEX
, FIOCLEX
),
1274 MAPPED_IOCTL_MAP(LINUX_FIOASYNC
, FIOASYNC
),
1276 MAPPED_IOCTL_MAP(LINUX_CDROMPAUSE
, CDIOCPAUSE
),
1277 MAPPED_IOCTL_MAP(LINUX_CDROMRESUME
, CDIOCRESUME
),
1278 MAPPED_IOCTL_MAP(LINUX_CDROMPLAYMSF
, CDIOCPLAYMSF
),
1279 MAPPED_IOCTL_MAP(LINUX_CDROMPLAYTRKIND
, CDIOCPLAYTRACKS
),
1280 MAPPED_IOCTL_IOR(LINUX_CDROMREADTOCHDR
, linux_ioctl_CDROMREADTOCHDR
, struct linux_cdrom_tochdr
),
1281 MAPPED_IOCTL_IOWR(LINUX_CDROMREADTOCENTRY
, linux_ioctl_CDROMREADTOCENTRY
, struct linux_cdrom_tocentry
),
1282 MAPPED_IOCTL_MAP(LINUX_CDROMSTOP
, CDIOCSTOP
),
1283 MAPPED_IOCTL_MAP(LINUX_CDROMSTART
, CDIOCSTART
),
1284 MAPPED_IOCTL_MAP(LINUX_CDROMEJECT
, CDIOCEJECT
),
1285 MAPPED_IOCTL_IOWR(LINUX_CDROMSUBCHNL
, linux_ioctl_CDROMSUBCHNL
, struct linux_cdrom_subchnl
),
1286 MAPPED_IOCTL_MAP(LINUX_CDROMRESET
, CDIOCRESET
),
1288 MAPPED_IOCTL_MAPRANGE(LINUX_SOUND_MIXER_WRITE_MIN
, LINUX_SOUND_MIXER_WRITE_MAX
,
1289 LINUX_SOUND_MIXER_WRITE_MIN
, LINUX_SOUND_MIXER_WRITE_MAX
,
1290 NULL
, linux_gen_dirmap
),
1291 MAPPED_IOCTL_IOR(LINUX_OSS_GETVERSION
, linux_ioctl_OSS_GETVERSION
, int),
1292 MAPPED_IOCTL_MAP(LINUX_SOUND_MIXER_READ_DEVMASK
, SOUND_MIXER_READ_DEVMASK
),
1293 MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_DSP_MIN
, LINUX_SNDCTL_DSP_MAX
, LINUX_SNDCTL_DSP_MIN
,
1294 LINUX_SNDCTL_DSP_MAX
, NULL
, linux_gen_dirmap
),
1295 MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_SEQ_MIN
, LINUX_SNDCTL_SEQ_MAX
, LINUX_SNDCTL_SEQ_MIN
,
1296 LINUX_SNDCTL_SEQ_MAX
, NULL
, linux_gen_dirmap
),
1298 MAPPED_IOCTL_MAP(LINUX_KIOCSOUND
, KIOCSOUND
),
1299 MAPPED_IOCTL_MAP(LINUX_KDMKTONE
, KDMKTONE
),
1300 MAPPED_IOCTL_MAP(LINUX_KDGETLED
, KDGETLED
),
1301 MAPPED_IOCTL_MAP(LINUX_KDSETLED
, KDSETLED
),
1302 MAPPED_IOCTL_MAP(LINUX_KDSETMODE
, KDSETMODE
),
1303 MAPPED_IOCTL_MAP(LINUX_KDGETMODE
, KDGETMODE
),
1304 MAPPED_IOCTL_MAP(LINUX_KDGKBMODE
, KDGKBMODE
),
1305 MAPPED_IOCTL_IOW(LINUX_KDSKBMODE
, linux_ioctl_KDSKBMODE
, int),
1306 MAPPED_IOCTL_MAP(LINUX_VT_OPENQRY
, VT_OPENQRY
),
1307 MAPPED_IOCTL_MAP(LINUX_VT_GETMODE
, VT_GETMODE
),
1308 MAPPED_IOCTL_IOW(LINUX_VT_SETMODE
, linux_ioctl_VT_SETMODE
, struct vt_mode
),
1309 MAPPED_IOCTL_MAP(LINUX_VT_GETSTATE
, VT_GETACTIVE
),
1310 MAPPED_IOCTL_MAP(LINUX_VT_RELDISP
, VT_RELDISP
),
1311 MAPPED_IOCTL_MAP(LINUX_VT_ACTIVATE
, VT_ACTIVATE
),
1312 MAPPED_IOCTL_MAP(LINUX_VT_WAITACTIVE
, VT_WAITACTIVE
),
1314 MAPPED_IOCTL_MAP(LINUX_FIOSETOWN
, FIOSETOWN
),
1315 MAPPED_IOCTL_MAP(LINUX_SIOCSPGRP
, SIOCSPGRP
),
1316 MAPPED_IOCTL_MAP(LINUX_FIOGETOWN
, FIOGETOWN
),
1317 MAPPED_IOCTL_MAP(LINUX_SIOCGPGRP
, SIOCGPGRP
),
1318 MAPPED_IOCTL_MAP(LINUX_SIOCATMARK
, SIOCATMARK
),
1319 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFCONF
, linux_ioctl_SIOCGIFCONF
, struct ifconf
),
1320 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFFLAGS
, linux_ioctl_SIOCGIFFLAGS
, struct l_ifreq
),
1321 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFADDR
, OSIOCGIFADDR
, linux_ioctl_map_ifname
),
1322 MAPPED_IOCTL_MAPF(LINUX_SIOCSIFADDR
, SIOCSIFADDR
, linux_ioctl_map_ifname
),
1323 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFDSTADDR
, OSIOCGIFDSTADDR
, linux_ioctl_map_ifname
),
1324 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFBRDADDR
, OSIOCGIFBRDADDR
, linux_ioctl_map_ifname
),
1325 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFNETMASK
, OSIOCGIFNETMASK
, linux_ioctl_map_ifname
),
1326 /*MAPPED_IOCTL_IOx(LINUX_SIOCSIFNETMASK, x, x),*/
1327 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFMTU
, SIOCGIFMTU
, linux_ioctl_map_ifname
),
1328 MAPPED_IOCTL_MAPF(LINUX_SIOCSIFMTU
, SIOCSIFMTU
, linux_ioctl_map_ifname
),
1329 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFHWADDR
, linux_ioctl_SIOGIFHWADDR
, struct l_ifreq
),
1330 MAPPED_IOCTL_IOR(LINUX_SIOCGIFINDEX
, linux_ioctl_SIOCGIFINDEX
, struct l_ifreq
),
1331 MAPPED_IOCTL_IOR(LINUX_SIOCGIFMETRIC
, linux_ioctl_SIOCGIFMETRIC
, struct l_ifreq
),
1332 MAPPED_IOCTL_MAP(LINUX_SIOCADDMULTI
, SIOCADDMULTI
),
1333 MAPPED_IOCTL_MAP(LINUX_SIOCDELMULTI
, SIOCDELMULTI
),
1335 * XXX This is slightly bogus, but these ioctls are currently
1336 * XXX only used by the aironet (if_an) network driver.
1338 MAPPED_IOCTL_MAPF(LINUX_SIOCDEVPRIVATE
, SIOCGPRIVATE_0
, linux_ioctl_map_ifname
),
1339 MAPPED_IOCTL_MAPF(LINUX_SIOCDEVPRIVATE
+1, SIOCGPRIVATE_1
, linux_ioctl_map_ifname
),
1340 MAPPED_IOCTL_MAPF(0, 0, NULL
)
1343 struct ioctl_map linux_ioctl_map
= {
1345 "linux", /* subsys */
1346 LIST_HEAD_INITIALIZER(mapping
)
1349 static struct ioctl_map_handler linux_ioctl_base_handler
= {
1352 linux_ioctl_map_entries
1356 * main ioctl syscall function
1361 sys_linux_ioctl(struct linux_ioctl_args
*args
)
1367 kprintf(ARGS(ioctl
, "%d, %04x, *"), args
->fd
, args
->cmd
);
1371 error
= mapped_ioctl(args
->fd
, args
->cmd
, (caddr_t
)args
->arg
,
1372 &linux_ioctl_map
, &args
->sysmsg
);
1377 SYSINIT (linux_ioctl_register
, SI_BOOT2_KLD
, SI_ORDER_MIDDLE
,
1378 mapped_ioctl_register_handler
, &linux_ioctl_base_handler
);
1379 SYSUNINIT(linux_ioctl_register
, SI_BOOT2_KLD
, SI_ORDER_MIDDLE
,
1380 mapped_ioctl_unregister_handler
, &linux_ioctl_base_handler
);