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>
58 #include <sys/file2.h>
60 #include <arch_linux/linux.h>
61 #include <arch_linux/linux_proto.h>
63 #include "linux_ioctl.h"
64 #include "linux_mib.h"
65 #include "linux_util.h"
69 linux_ioctl_BLKGETSIZE32(struct file
*fp
, u_long cmd
, u_long ocmd
,
70 caddr_t data
, struct ucred
*cred
)
72 struct partinfo dpart
;
76 error
= fo_ioctl(fp
, DIOCGPART
, (caddr_t
)&dpart
, cred
);
79 value
= dpart
.media_blocks
; /* 64->32 */
80 bcopy(&value
, data
, sizeof(value
));
86 * termio related ioctls
90 unsigned short c_iflag
;
91 unsigned short c_oflag
;
92 unsigned short c_cflag
;
93 unsigned short c_lflag
;
95 unsigned char c_cc
[LINUX_NCC
];
98 struct linux_termios
{
100 unsigned int c_oflag
;
101 unsigned int c_cflag
;
102 unsigned int c_lflag
;
103 unsigned char c_line
;
104 unsigned char c_cc
[LINUX_NCCS
];
107 struct linux_winsize
{
108 unsigned short ws_row
, ws_col
;
109 unsigned short ws_xpixel
, ws_ypixel
;
112 static struct speedtab sptab
[] = {
113 { B0
, LINUX_B0
}, { B50
, LINUX_B50
},
114 { B75
, LINUX_B75
}, { B110
, LINUX_B110
},
115 { B134
, LINUX_B134
}, { B150
, LINUX_B150
},
116 { B200
, LINUX_B200
}, { B300
, LINUX_B300
},
117 { B600
, LINUX_B600
}, { B1200
, LINUX_B1200
},
118 { B1800
, LINUX_B1800
}, { B2400
, LINUX_B2400
},
119 { B4800
, LINUX_B4800
}, { B9600
, LINUX_B9600
},
120 { B19200
, LINUX_B19200
}, { B38400
, LINUX_B38400
},
121 { B57600
, LINUX_B57600
}, { B115200
, LINUX_B115200
},
125 struct linux_serial_struct
{
134 unsigned short close_delay
;
135 char reserved_char
[2];
137 unsigned short closing_wait
;
138 unsigned short closing_wait2
;
143 linux_to_bsd_speed(int code
, struct speedtab
*table
)
145 for ( ; table
->sp_code
!= -1; table
++)
146 if (table
->sp_code
== code
)
147 return (table
->sp_speed
);
152 bsd_to_linux_speed(int speed
, struct speedtab
*table
)
154 for ( ; table
->sp_speed
!= -1; table
++)
155 if (table
->sp_speed
== speed
)
156 return (table
->sp_code
);
161 bsd_to_linux_termios(struct termios
*bios
, struct linux_termios
*lios
)
167 kprintf("LINUX: BSD termios structure (input):\n");
168 kprintf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
169 bios
->c_iflag
, bios
->c_oflag
, bios
->c_cflag
, bios
->c_lflag
,
170 bios
->c_ispeed
, bios
->c_ospeed
);
172 for (i
=0; i
<NCCS
; i
++)
173 kprintf("%02x ", bios
->c_cc
[i
]);
179 if (bios
->c_iflag
& IGNBRK
)
180 lios
->c_iflag
|= LINUX_IGNBRK
;
181 if (bios
->c_iflag
& BRKINT
)
182 lios
->c_iflag
|= LINUX_BRKINT
;
183 if (bios
->c_iflag
& IGNPAR
)
184 lios
->c_iflag
|= LINUX_IGNPAR
;
185 if (bios
->c_iflag
& PARMRK
)
186 lios
->c_iflag
|= LINUX_PARMRK
;
187 if (bios
->c_iflag
& INPCK
)
188 lios
->c_iflag
|= LINUX_INPCK
;
189 if (bios
->c_iflag
& ISTRIP
)
190 lios
->c_iflag
|= LINUX_ISTRIP
;
191 if (bios
->c_iflag
& INLCR
)
192 lios
->c_iflag
|= LINUX_INLCR
;
193 if (bios
->c_iflag
& IGNCR
)
194 lios
->c_iflag
|= LINUX_IGNCR
;
195 if (bios
->c_iflag
& ICRNL
)
196 lios
->c_iflag
|= LINUX_ICRNL
;
197 if (bios
->c_iflag
& IXON
)
198 lios
->c_iflag
|= LINUX_IXON
;
199 if (bios
->c_iflag
& IXANY
)
200 lios
->c_iflag
|= LINUX_IXANY
;
201 if (bios
->c_iflag
& IXOFF
)
202 lios
->c_iflag
|= LINUX_IXOFF
;
203 if (bios
->c_iflag
& IMAXBEL
)
204 lios
->c_iflag
|= LINUX_IMAXBEL
;
207 if (bios
->c_oflag
& OPOST
)
208 lios
->c_oflag
|= LINUX_OPOST
;
209 if (bios
->c_oflag
& ONLCR
)
210 lios
->c_oflag
|= LINUX_ONLCR
;
211 if (bios
->c_oflag
& OXTABS
)
212 lios
->c_oflag
|= LINUX_XTABS
;
214 lios
->c_cflag
= bsd_to_linux_speed(bios
->c_ispeed
, sptab
);
215 lios
->c_cflag
|= (bios
->c_cflag
& CSIZE
) >> 4;
216 if (bios
->c_cflag
& CSTOPB
)
217 lios
->c_cflag
|= LINUX_CSTOPB
;
218 if (bios
->c_cflag
& CREAD
)
219 lios
->c_cflag
|= LINUX_CREAD
;
220 if (bios
->c_cflag
& PARENB
)
221 lios
->c_cflag
|= LINUX_PARENB
;
222 if (bios
->c_cflag
& PARODD
)
223 lios
->c_cflag
|= LINUX_PARODD
;
224 if (bios
->c_cflag
& HUPCL
)
225 lios
->c_cflag
|= LINUX_HUPCL
;
226 if (bios
->c_cflag
& CLOCAL
)
227 lios
->c_cflag
|= LINUX_CLOCAL
;
228 if (bios
->c_cflag
& CRTSCTS
)
229 lios
->c_cflag
|= LINUX_CRTSCTS
;
232 if (bios
->c_lflag
& ISIG
)
233 lios
->c_lflag
|= LINUX_ISIG
;
234 if (bios
->c_lflag
& ICANON
)
235 lios
->c_lflag
|= LINUX_ICANON
;
236 if (bios
->c_lflag
& ECHO
)
237 lios
->c_lflag
|= LINUX_ECHO
;
238 if (bios
->c_lflag
& ECHOE
)
239 lios
->c_lflag
|= LINUX_ECHOE
;
240 if (bios
->c_lflag
& ECHOK
)
241 lios
->c_lflag
|= LINUX_ECHOK
;
242 if (bios
->c_lflag
& ECHONL
)
243 lios
->c_lflag
|= LINUX_ECHONL
;
244 if (bios
->c_lflag
& NOFLSH
)
245 lios
->c_lflag
|= LINUX_NOFLSH
;
246 if (bios
->c_lflag
& TOSTOP
)
247 lios
->c_lflag
|= LINUX_TOSTOP
;
248 if (bios
->c_lflag
& ECHOCTL
)
249 lios
->c_lflag
|= LINUX_ECHOCTL
;
250 if (bios
->c_lflag
& ECHOPRT
)
251 lios
->c_lflag
|= LINUX_ECHOPRT
;
252 if (bios
->c_lflag
& ECHOKE
)
253 lios
->c_lflag
|= LINUX_ECHOKE
;
254 if (bios
->c_lflag
& FLUSHO
)
255 lios
->c_lflag
|= LINUX_FLUSHO
;
256 if (bios
->c_lflag
& PENDIN
)
257 lios
->c_lflag
|= LINUX_PENDIN
;
258 if (bios
->c_lflag
& IEXTEN
)
259 lios
->c_lflag
|= LINUX_IEXTEN
;
261 for (i
=0; i
<LINUX_NCCS
; i
++)
262 lios
->c_cc
[i
] = LINUX_POSIX_VDISABLE
;
263 lios
->c_cc
[LINUX_VINTR
] = bios
->c_cc
[VINTR
];
264 lios
->c_cc
[LINUX_VQUIT
] = bios
->c_cc
[VQUIT
];
265 lios
->c_cc
[LINUX_VERASE
] = bios
->c_cc
[VERASE
];
266 lios
->c_cc
[LINUX_VKILL
] = bios
->c_cc
[VKILL
];
267 lios
->c_cc
[LINUX_VEOF
] = bios
->c_cc
[VEOF
];
268 lios
->c_cc
[LINUX_VEOL
] = bios
->c_cc
[VEOL
];
269 lios
->c_cc
[LINUX_VMIN
] = bios
->c_cc
[VMIN
];
270 lios
->c_cc
[LINUX_VTIME
] = bios
->c_cc
[VTIME
];
271 lios
->c_cc
[LINUX_VEOL2
] = bios
->c_cc
[VEOL2
];
272 lios
->c_cc
[LINUX_VSUSP
] = bios
->c_cc
[VSUSP
];
273 lios
->c_cc
[LINUX_VSTART
] = bios
->c_cc
[VSTART
];
274 lios
->c_cc
[LINUX_VSTOP
] = bios
->c_cc
[VSTOP
];
275 lios
->c_cc
[LINUX_VREPRINT
] = bios
->c_cc
[VREPRINT
];
276 lios
->c_cc
[LINUX_VDISCARD
] = bios
->c_cc
[VDISCARD
];
277 lios
->c_cc
[LINUX_VWERASE
] = bios
->c_cc
[VWERASE
];
278 lios
->c_cc
[LINUX_VLNEXT
] = bios
->c_cc
[VLNEXT
];
280 for (i
=0; i
<LINUX_NCCS
; i
++) {
281 if (i
!= LINUX_VMIN
&& i
!= LINUX_VTIME
&&
282 lios
->c_cc
[i
] == _POSIX_VDISABLE
)
283 lios
->c_cc
[i
] = LINUX_POSIX_VDISABLE
;
289 kprintf("LINUX: LINUX termios structure (output):\n");
290 kprintf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
291 lios
->c_iflag
, lios
->c_oflag
, lios
->c_cflag
,
292 lios
->c_lflag
, (int)lios
->c_line
);
294 for (i
=0; i
<LINUX_NCCS
; i
++)
295 kprintf("%02x ", lios
->c_cc
[i
]);
302 linux_to_bsd_termios(struct linux_termios
*lios
, struct termios
*bios
)
308 kprintf("LINUX: LINUX termios structure (input):\n");
309 kprintf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
310 lios
->c_iflag
, lios
->c_oflag
, lios
->c_cflag
,
311 lios
->c_lflag
, (int)lios
->c_line
);
313 for (i
=0; i
<LINUX_NCCS
; i
++)
314 kprintf("%02x ", lios
->c_cc
[i
]);
320 if (lios
->c_iflag
& LINUX_IGNBRK
)
321 bios
->c_iflag
|= IGNBRK
;
322 if (lios
->c_iflag
& LINUX_BRKINT
)
323 bios
->c_iflag
|= BRKINT
;
324 if (lios
->c_iflag
& LINUX_IGNPAR
)
325 bios
->c_iflag
|= IGNPAR
;
326 if (lios
->c_iflag
& LINUX_PARMRK
)
327 bios
->c_iflag
|= PARMRK
;
328 if (lios
->c_iflag
& LINUX_INPCK
)
329 bios
->c_iflag
|= INPCK
;
330 if (lios
->c_iflag
& LINUX_ISTRIP
)
331 bios
->c_iflag
|= ISTRIP
;
332 if (lios
->c_iflag
& LINUX_INLCR
)
333 bios
->c_iflag
|= INLCR
;
334 if (lios
->c_iflag
& LINUX_IGNCR
)
335 bios
->c_iflag
|= IGNCR
;
336 if (lios
->c_iflag
& LINUX_ICRNL
)
337 bios
->c_iflag
|= ICRNL
;
338 if (lios
->c_iflag
& LINUX_IXON
)
339 bios
->c_iflag
|= IXON
;
340 if (lios
->c_iflag
& LINUX_IXANY
)
341 bios
->c_iflag
|= IXANY
;
342 if (lios
->c_iflag
& LINUX_IXOFF
)
343 bios
->c_iflag
|= IXOFF
;
344 if (lios
->c_iflag
& LINUX_IMAXBEL
)
345 bios
->c_iflag
|= IMAXBEL
;
348 if (lios
->c_oflag
& LINUX_OPOST
)
349 bios
->c_oflag
|= OPOST
;
350 if (lios
->c_oflag
& LINUX_ONLCR
)
351 bios
->c_oflag
|= ONLCR
;
352 if (lios
->c_oflag
& LINUX_XTABS
)
353 bios
->c_oflag
|= OXTABS
;
355 bios
->c_cflag
= (lios
->c_cflag
& LINUX_CSIZE
) << 4;
356 if (lios
->c_cflag
& LINUX_CSTOPB
)
357 bios
->c_cflag
|= CSTOPB
;
358 if (lios
->c_cflag
& LINUX_CREAD
)
359 bios
->c_cflag
|= CREAD
;
360 if (lios
->c_cflag
& LINUX_PARENB
)
361 bios
->c_cflag
|= PARENB
;
362 if (lios
->c_cflag
& LINUX_PARODD
)
363 bios
->c_cflag
|= PARODD
;
364 if (lios
->c_cflag
& LINUX_HUPCL
)
365 bios
->c_cflag
|= HUPCL
;
366 if (lios
->c_cflag
& LINUX_CLOCAL
)
367 bios
->c_cflag
|= CLOCAL
;
368 if (lios
->c_cflag
& LINUX_CRTSCTS
)
369 bios
->c_cflag
|= CRTSCTS
;
372 if (lios
->c_lflag
& LINUX_ISIG
)
373 bios
->c_lflag
|= ISIG
;
374 if (lios
->c_lflag
& LINUX_ICANON
)
375 bios
->c_lflag
|= ICANON
;
376 if (lios
->c_lflag
& LINUX_ECHO
)
377 bios
->c_lflag
|= ECHO
;
378 if (lios
->c_lflag
& LINUX_ECHOE
)
379 bios
->c_lflag
|= ECHOE
;
380 if (lios
->c_lflag
& LINUX_ECHOK
)
381 bios
->c_lflag
|= ECHOK
;
382 if (lios
->c_lflag
& LINUX_ECHONL
)
383 bios
->c_lflag
|= ECHONL
;
384 if (lios
->c_lflag
& LINUX_NOFLSH
)
385 bios
->c_lflag
|= NOFLSH
;
386 if (lios
->c_lflag
& LINUX_TOSTOP
)
387 bios
->c_lflag
|= TOSTOP
;
388 if (lios
->c_lflag
& LINUX_ECHOCTL
)
389 bios
->c_lflag
|= ECHOCTL
;
390 if (lios
->c_lflag
& LINUX_ECHOPRT
)
391 bios
->c_lflag
|= ECHOPRT
;
392 if (lios
->c_lflag
& LINUX_ECHOKE
)
393 bios
->c_lflag
|= ECHOKE
;
394 if (lios
->c_lflag
& LINUX_FLUSHO
)
395 bios
->c_lflag
|= FLUSHO
;
396 if (lios
->c_lflag
& LINUX_PENDIN
)
397 bios
->c_lflag
|= PENDIN
;
398 if (lios
->c_lflag
& LINUX_IEXTEN
)
399 bios
->c_lflag
|= IEXTEN
;
401 for (i
=0; i
<NCCS
; i
++)
402 bios
->c_cc
[i
] = _POSIX_VDISABLE
;
403 bios
->c_cc
[VINTR
] = lios
->c_cc
[LINUX_VINTR
];
404 bios
->c_cc
[VQUIT
] = lios
->c_cc
[LINUX_VQUIT
];
405 bios
->c_cc
[VERASE
] = lios
->c_cc
[LINUX_VERASE
];
406 bios
->c_cc
[VKILL
] = lios
->c_cc
[LINUX_VKILL
];
407 bios
->c_cc
[VEOF
] = lios
->c_cc
[LINUX_VEOF
];
408 bios
->c_cc
[VEOL
] = lios
->c_cc
[LINUX_VEOL
];
409 bios
->c_cc
[VMIN
] = lios
->c_cc
[LINUX_VMIN
];
410 bios
->c_cc
[VTIME
] = lios
->c_cc
[LINUX_VTIME
];
411 bios
->c_cc
[VEOL2
] = lios
->c_cc
[LINUX_VEOL2
];
412 bios
->c_cc
[VSUSP
] = lios
->c_cc
[LINUX_VSUSP
];
413 bios
->c_cc
[VSTART
] = lios
->c_cc
[LINUX_VSTART
];
414 bios
->c_cc
[VSTOP
] = lios
->c_cc
[LINUX_VSTOP
];
415 bios
->c_cc
[VREPRINT
] = lios
->c_cc
[LINUX_VREPRINT
];
416 bios
->c_cc
[VDISCARD
] = lios
->c_cc
[LINUX_VDISCARD
];
417 bios
->c_cc
[VWERASE
] = lios
->c_cc
[LINUX_VWERASE
];
418 bios
->c_cc
[VLNEXT
] = lios
->c_cc
[LINUX_VLNEXT
];
420 for (i
=0; i
<NCCS
; i
++) {
421 if (i
!= VMIN
&& i
!= VTIME
&&
422 bios
->c_cc
[i
] == LINUX_POSIX_VDISABLE
)
423 bios
->c_cc
[i
] = _POSIX_VDISABLE
;
426 bios
->c_ispeed
= bios
->c_ospeed
=
427 linux_to_bsd_speed(lios
->c_cflag
& LINUX_CBAUD
, sptab
);
431 kprintf("LINUX: BSD termios structure (output):\n");
432 kprintf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
433 bios
->c_iflag
, bios
->c_oflag
, bios
->c_cflag
, bios
->c_lflag
,
434 bios
->c_ispeed
, bios
->c_ospeed
);
436 for (i
=0; i
<NCCS
; i
++)
437 kprintf("%02x ", bios
->c_cc
[i
]);
444 bsd_to_linux_termio(struct termios
*bios
, struct linux_termio
*lio
)
446 struct linux_termios lios
;
448 bsd_to_linux_termios(bios
, &lios
);
449 lio
->c_iflag
= lios
.c_iflag
;
450 lio
->c_oflag
= lios
.c_oflag
;
451 lio
->c_cflag
= lios
.c_cflag
;
452 lio
->c_lflag
= lios
.c_lflag
;
453 lio
->c_line
= lios
.c_line
;
454 memcpy(lio
->c_cc
, lios
.c_cc
, LINUX_NCC
);
458 linux_to_bsd_termio(struct linux_termio
*lio
, struct termios
*bios
)
460 struct linux_termios lios
;
463 lios
.c_iflag
= lio
->c_iflag
;
464 lios
.c_oflag
= lio
->c_oflag
;
465 lios
.c_cflag
= lio
->c_cflag
;
466 lios
.c_lflag
= lio
->c_lflag
;
467 for (i
=LINUX_NCC
; i
<LINUX_NCCS
; i
++)
468 lios
.c_cc
[i
] = LINUX_POSIX_VDISABLE
;
469 memcpy(lios
.c_cc
, lio
->c_cc
, LINUX_NCC
);
470 linux_to_bsd_termios(&lios
, bios
);
474 linux_ioctl_TCGETS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
477 struct linux_termios lios
;
480 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
);
483 bsd_to_linux_termios(&bios
, &lios
);
484 bcopy(&lios
, data
, sizeof(lios
));
489 linux_ioctl_TCSETS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
492 struct linux_termios lios
;
494 bcopy(data
, &lios
, sizeof(lios
));
495 linux_to_bsd_termios(&lios
, &bios
);
496 return (fo_ioctl(fp
, TIOCSETA
, (caddr_t
)&bios
, cred
));
500 linux_ioctl_TCSETSW(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
503 struct linux_termios lios
;
505 bcopy(data
, &lios
, sizeof(lios
));
506 linux_to_bsd_termios(&lios
, &bios
);
507 return (fo_ioctl(fp
, TIOCSETAW
, (caddr_t
)&bios
, cred
));
511 linux_ioctl_TCSETSF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
514 struct linux_termios lios
;
516 bcopy(data
, &lios
, sizeof(lios
));
517 linux_to_bsd_termios(&lios
, &bios
);
518 return (fo_ioctl(fp
, TIOCSETAF
, (caddr_t
)&bios
, cred
));
522 linux_ioctl_TCGETA(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
525 struct linux_termio lio
;
528 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
);
531 bsd_to_linux_termio(&bios
, &lio
);
532 bcopy(&lio
, data
, sizeof(lio
));
537 linux_ioctl_TCSETA(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
540 struct linux_termio lio
;
542 bcopy(data
, &lio
, sizeof(lio
));
543 linux_to_bsd_termio(&lio
, &bios
);
544 return (fo_ioctl(fp
, TIOCSETA
, (caddr_t
)&bios
, cred
));
548 linux_ioctl_TCSETAW(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
551 struct linux_termio lio
;
553 bcopy(data
, &lio
, sizeof(lio
));
554 linux_to_bsd_termio(&lio
, &bios
);
555 return (fo_ioctl(fp
, TIOCSETAW
, (caddr_t
)&bios
, cred
));
559 linux_ioctl_TCSETAF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
562 struct linux_termio lio
;
564 bcopy(data
, &lio
, sizeof(lio
));
565 linux_to_bsd_termio(&lio
, &bios
);
566 return (fo_ioctl(fp
, TIOCSETAF
, (caddr_t
)&bios
, cred
));
570 linux_ioctl_TCXONC(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
572 switch ((u_long
)data
) {
584 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
);
587 c
= ((u_long
)data
== LINUX_TCIOFF
) ? VSTOP
: VSTART
;
589 if (c
!= _POSIX_VDISABLE
) {
593 aiov
.iov_base
= (char *)&c
;
594 aiov
.iov_len
= sizeof(*bios
.c_cc
);
595 auio
.uio_iov
= &aiov
;
597 auio
.uio_offset
= -1;
598 auio
.uio_resid
= sizeof(*bios
.c_cc
);
599 auio
.uio_rw
= UIO_WRITE
;
600 auio
.uio_segflg
= UIO_SYSSPACE
;
601 auio
.uio_td
= curthread
;
603 return (fo_write(fp
, &auio
, fp
->f_cred
, 0));
611 return (fo_ioctl(fp
, cmd
, 0, cred
));
615 linux_ioctl_TCFLSH(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
617 switch ((u_long
)data
) {
619 *(u_long
*)data
= FREAD
;
622 *(u_long
*)data
= FWRITE
;
624 case LINUX_TCIOFLUSH
:
625 *(u_long
*)data
= FREAD
| FWRITE
;
630 return (fo_ioctl(fp
, TIOCFLUSH
, data
, cred
));
634 linux_ioctl_TIOCGSERIAL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
636 struct linux_serial_struct lss
;
638 lss
.type
= LINUX_PORT_16550A
;
641 bcopy(&lss
, data
, sizeof(lss
));
646 linux_ioctl_TIOCSSERIAL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
649 struct linux_serial_struct lss
;
651 bcopy(data
, &lss
, sizeof(lss
));
652 /* XXX - It really helps to have an implementation that
660 linux_ioctl_TIOCSETD(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
664 switch ((u_long
)data
) {
677 return (fo_ioctl(fp
, TIOCSETD
, (caddr_t
)&line
, cred
));
681 linux_ioctl_TIOCGETD(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
683 int linux_line
, error
;
684 int bsd_line
= TTYDISC
;
686 error
= fo_ioctl(fp
, TIOCGETD
, (caddr_t
)&bsd_line
, cred
);
691 linux_line
= LINUX_N_TTY
;
694 linux_line
= LINUX_N_SLIP
;
697 linux_line
= LINUX_N_PPP
;
702 bcopy(&linux_line
, data
, sizeof(int));
708 * CDROM related ioctls
711 struct linux_cdrom_msf
721 struct linux_cdrom_tochdr
727 union linux_cdrom_addr
737 struct linux_cdrom_tocentry
743 union linux_cdrom_addr cdte_addr
;
744 u_char cdte_datamode
;
747 struct linux_cdrom_subchnl
750 u_char cdsc_audiostatus
;
755 union linux_cdrom_addr cdsc_absaddr
;
756 union linux_cdrom_addr cdsc_reladdr
;
760 bsd_to_linux_msf_lba(u_char af
, union msf_lba
*bp
, union linux_cdrom_addr
*lp
)
762 if (af
== CD_LBA_FORMAT
)
765 lp
->msf
.minute
= bp
->msf
.minute
;
766 lp
->msf
.second
= bp
->msf
.second
;
767 lp
->msf
.frame
= bp
->msf
.frame
;
772 set_linux_cdrom_addr(union linux_cdrom_addr
*addr
, int format
, int lba
)
774 if (format
== LINUX_CDROM_MSF
) {
775 addr
->msf
.frame
= lba
% 75;
778 addr
->msf
.second
= lba
% 60;
779 addr
->msf
.minute
= lba
/ 60;
785 linux_ioctl_CDROMREADTOCHDR(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
787 struct ioc_toc_header th
;
788 struct linux_cdrom_tochdr lth
;
791 error
= fo_ioctl(fp
, CDIOREADTOCHEADER
, (caddr_t
)&th
, cred
);
794 lth
.cdth_trk0
= th
.starting_track
;
795 lth
.cdth_trk1
= th
.ending_track
;
796 bcopy(<h
, data
, sizeof(lth
));
801 linux_ioctl_CDROMREADTOCENTRY(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
803 struct linux_cdrom_tocentry
*ltep
= (struct linux_cdrom_tocentry
*)data
;
804 struct ioc_read_toc_single_entry irtse
;
807 irtse
.address_format
= ltep
->cdte_format
;
808 irtse
.track
= ltep
->cdte_track
;
809 error
= fo_ioctl(fp
, CDIOREADTOCENTRY
, (caddr_t
)&irtse
, cred
);
813 ltep
->cdte_ctrl
= irtse
.entry
.control
;
814 ltep
->cdte_adr
= irtse
.entry
.addr_type
;
815 bsd_to_linux_msf_lba(irtse
.address_format
, &irtse
.entry
.addr
,
821 linux_ioctl_CDROMSUBCHNL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
823 struct linux_cdrom_subchnl
*sc
= (struct linux_cdrom_subchnl
*)data
;
824 struct ioc_read_subchannel bsdsc
;
825 struct cd_sub_channel_info
*bsdinfo
;
827 caddr_t sg
= stackgap_init();
829 bsdinfo
= stackgap_alloc(&sg
, sizeof(struct cd_sub_channel_info
));
830 bsdsc
.address_format
= CD_LBA_FORMAT
;
831 bsdsc
.data_format
= CD_CURRENT_POSITION
;
833 bsdsc
.data_len
= sizeof(struct cd_sub_channel_info
);
834 bsdsc
.data
= bsdinfo
;
835 error
= fo_ioctl(fp
, CDIOCREADSUBCHANNEL
, (caddr_t
)&bsdsc
, cred
);
838 sc
->cdsc_audiostatus
= bsdinfo
->header
.audio_status
;
839 sc
->cdsc_adr
= bsdinfo
->what
.position
.addr_type
;
840 sc
->cdsc_ctrl
= bsdinfo
->what
.position
.control
;
841 sc
->cdsc_trk
= bsdinfo
->what
.position
.track_number
;
842 sc
->cdsc_ind
= bsdinfo
->what
.position
.index_number
;
843 set_linux_cdrom_addr(&sc
->cdsc_absaddr
, sc
->cdsc_format
, bsdinfo
->what
.position
.absaddr
.lba
);
844 set_linux_cdrom_addr(&sc
->cdsc_reladdr
, sc
->cdsc_format
, bsdinfo
->what
.position
.reladdr
.lba
);
850 * Sound related ioctls
854 linux_ioctl_OSS_GETVERSION(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
856 int version
= linux_get_oss_version(curthread
);
858 bcopy(&version
, data
, sizeof(int));
864 * Console related ioctls
867 #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
870 linux_ioctl_KDSKBMODE(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
874 switch ((u_long
)data
) {
878 case LINUX_KBD_XLATE
:
881 case LINUX_KBD_MEDIUMRAW
:
887 return (fo_ioctl(fp
, KDSKBMODE
, (caddr_t
)&kbdmode
, cred
));
891 linux_ioctl_VT_SETMODE(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
893 struct vt_mode
*mode
= (struct vt_mode
*)data
;
895 if (!ISSIGVALID(mode
->frsig
) && ISSIGVALID(mode
->acqsig
))
896 mode
->frsig
= mode
->acqsig
;
897 return (fo_ioctl(fp
, VT_SETMODE
, data
, cred
));
902 * Socket related ioctls
906 * Criteria for interface name translation
908 #define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
911 * Interface function used by linprocfs (at the time of writing). It's not
912 * used by the Linuxulator itself.
915 linux_ifname(struct ifnet
*ifp
, char *buffer
, size_t buflen
)
917 struct ifnet
*ifscan
;
920 /* Short-circuit non ethernet interfaces */
921 if (!IFP_IS_ETH(ifp
))
922 return (strlcpy(buffer
, ifp
->if_xname
, buflen
));
924 /* Determine the (relative) unit number for ethernet interfaces */
926 TAILQ_FOREACH(ifscan
, &ifnet
, if_link
) {
928 return (ksnprintf(buffer
, buflen
, "eth%d", ethno
));
929 if (IFP_IS_ETH(ifscan
))
937 * Translate a Linux interface name to a FreeBSD interface name,
938 * and return the associated ifnet structure
939 * bsdname and lxname need to be least IFNAMSIZ bytes long, but
940 * can point to the same buffer.
943 static struct ifnet
*
944 ifname_linux_to_bsd(const char *lxname
, char *bsdname
)
951 for (len
= 0; len
< LINUX_IFNAMSIZ
; ++len
)
952 if (!isalpha(lxname
[len
]))
954 if (len
== 0 || len
== LINUX_IFNAMSIZ
)
956 unit
= (int)strtoul(lxname
+ len
, &ep
, 10);
957 if (ep
== NULL
|| ep
== lxname
+ len
|| ep
>= lxname
+ LINUX_IFNAMSIZ
)
960 is_eth
= (len
== 3 && !strncmp(lxname
, "eth", len
)) ? 1 : 0;
961 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
963 * Allow Linux programs to use FreeBSD names. Don't presume
964 * we never have an interface named "eth", so don't make
965 * the test optional based on is_eth.
967 if (strncmp(ifp
->if_xname
, lxname
, LINUX_IFNAMSIZ
) == 0)
969 if (is_eth
&& IFP_IS_ETH(ifp
) && unit
== index
++)
973 strlcpy(bsdname
, ifp
->if_xname
, IFNAMSIZ
);
978 linux_ioctl_SIOCGIFCONF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
980 struct ifconf
*ifc
= (struct ifconf
*)data
;
987 /* much easier to use uiomove than keep track ourselves */
988 iov
.iov_base
= ifc
->ifc_buf
;
989 iov
.iov_len
= ifc
->ifc_len
;
993 uio
.uio_resid
= ifc
->ifc_len
;
994 uio
.uio_segflg
= UIO_USERSPACE
;
995 uio
.uio_rw
= UIO_READ
;
996 uio
.uio_td
= curthread
;
998 /* Keep track of eth interfaces */
1001 /* Return all AF_INET addresses of all interfaces */
1002 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
1003 struct ifaddr_container
*ifac
;
1005 if (uio
.uio_resid
<= 0)
1008 bzero(&ifr
, sizeof ifr
);
1009 if (IFP_IS_ETH(ifp
))
1010 ksnprintf(ifr
.ifr_name
, LINUX_IFNAMSIZ
, "eth%d",
1013 strlcpy(ifr
.ifr_name
, ifp
->if_xname
, LINUX_IFNAMSIZ
);
1015 /* Walk the address list */
1016 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1017 struct ifaddr
*ifa
= ifac
->ifa
;
1018 struct sockaddr
*sa
= ifa
->ifa_addr
;
1020 if (uio
.uio_resid
<= 0)
1023 if (sa
->sa_family
== AF_INET
) {
1024 ifr
.ifr_addr
.sa_family
= LINUX_AF_INET
;
1025 memcpy(ifr
.ifr_addr
.sa_data
, sa
->sa_data
,
1026 sizeof(ifr
.ifr_addr
.sa_data
));
1028 error
= uiomove((caddr_t
)&ifr
, sizeof ifr
,
1036 ifc
->ifc_len
-= uio
.uio_resid
;
1042 linux_ioctl_SIOCGIFFLAGS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1044 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1046 char ifname
[IFNAMSIZ
];
1049 if (fp
->f_type
!= DTYPE_SOCKET
) {
1050 /* XXX: I doubt this is correct because
1051 * we don't translate the ifname and
1052 * use l_ifreq instead of ifreq
1054 return (fo_ioctl(fp
, SIOCGIFFLAGS
, data
, cred
));
1057 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1058 flags
= ifp
->if_flags
;
1059 /* these flags have no Linux equivalent */
1060 flags
&= ~(IFF_SMART
|IFF_OACTIVE
|IFF_SIMPLEX
|
1061 IFF_LINK0
|IFF_LINK1
|IFF_LINK2
);
1062 /* Linux' multicast flag is in a different bit */
1063 if (flags
& IFF_MULTICAST
) {
1064 flags
&= ~IFF_MULTICAST
;
1068 ifr
->ifr_flags
= flags
;
1072 #define ARPHRD_ETHER 1
1073 #define ARPHRD_LOOPBACK 772
1076 linux_ioctl_SIOGIFHWADDR(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1078 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1080 char ifname
[IFNAMSIZ
];
1081 struct sockaddr_dl
*sdl
;
1082 struct l_sockaddr lsa
;
1083 struct ifaddr_container
*ifac
;
1085 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1086 if (ifp
->if_type
== IFT_LOOP
) {
1087 bzero(&ifr
->ifr_hwaddr
, sizeof lsa
);
1088 ifr
->ifr_hwaddr
.sa_family
= ARPHRD_LOOPBACK
;
1092 if (ifp
->if_type
!= IFT_ETHER
)
1095 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1096 struct ifaddr
*ifa
= ifac
->ifa
;
1098 sdl
= (struct sockaddr_dl
*)ifa
->ifa_addr
;
1099 if (sdl
!= NULL
&& (sdl
->sdl_family
== AF_LINK
) &&
1100 (sdl
->sdl_type
== IFT_ETHER
)) {
1101 bzero(&ifr
->ifr_hwaddr
, sizeof lsa
);
1102 ifr
->ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
1103 bcopy(LLADDR(sdl
), ifr
->ifr_hwaddr
.sa_data
, LINUX_IFHWADDRLEN
);
1112 linux_ioctl_map_ifname(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1116 char *oifname
= (char *)data
;
1117 char lifname
[LINUX_IFNAMSIZ
];
1119 KASSERT(LINUX_IFNAMSIZ
== IFNAMSIZ
,
1120 ("%s(): LINUX_IFNAMSIZ != IFNAMSIZ", __func__
));
1122 if (fp
->f_type
!= DTYPE_SOCKET
) {
1124 * XXX: I doubt this is correct because
1125 * we don't map the ifname
1127 /* not a socket - probably a tap / vmnet device */
1128 if (ocmd
== LINUX_SIOCGIFADDR
|| ocmd
== LINUX_SIOCSIFADDR
) {
1129 cmd
= (ocmd
== LINUX_SIOCGIFADDR
) ? SIOCGIFADDR
: SIOCSIFADDR
;
1130 return (fo_ioctl(fp
, cmd
, data
, cred
));
1135 /* Save the original ifname */
1136 bcopy(oifname
, lifname
, LINUX_IFNAMSIZ
);
1138 kprintf("%s(): ioctl %d on %.*s\n", __func__
,
1139 (int)(cmd
& 0xffff), LINUX_IFNAMSIZ
, lifname
);
1141 /* Replace linux ifname with bsd ifname */
1142 ifp
= ifname_linux_to_bsd(lifname
, oifname
);
1149 kprintf("%s(): %s translated to %s\n", __func__
,
1153 error
= fo_ioctl(fp
, cmd
, data
, cred
);
1156 bcopy(lifname
, oifname
, LINUX_IFNAMSIZ
);
1162 * generic linux -> BSD syscall direction mapper
1165 linux_gen_dirmap(u_long lstart
, u_long lend
, u_long bstart
, u_long bend
, u_long cmd
, u_long ocmd
)
1167 static u_int32_t dirbits
[4] = { IOC_VOID
, IOC_IN
, IOC_OUT
, IOC_INOUT
};
1169 return ((cmd
& ~IOC_DIRMASK
) | dirbits
[ocmd
>> 30]);
1173 static struct ioctl_map_range linux_ioctl_map_entries
[] = {
1175 MAPPED_IOCTL_IOR(LINUX_BLKGETSIZE
, linux_ioctl_BLKGETSIZE32
, uint32_t),
1177 MAPPED_IOCTL_IOR(LINUX_TCGETS
, linux_ioctl_TCGETS
, struct linux_termios
),
1178 MAPPED_IOCTL_IOW(LINUX_TCSETS
, linux_ioctl_TCSETS
, struct linux_termios
),
1179 MAPPED_IOCTL_IOW(LINUX_TCSETSW
, linux_ioctl_TCSETSW
, struct linux_termios
),
1180 MAPPED_IOCTL_IOW(LINUX_TCSETSF
, linux_ioctl_TCSETSF
, struct linux_termios
),
1181 MAPPED_IOCTL_IOR(LINUX_TCGETA
, linux_ioctl_TCGETA
, struct linux_termio
),
1182 MAPPED_IOCTL_IOW(LINUX_TCSETA
, linux_ioctl_TCSETA
, struct linux_termio
),
1183 MAPPED_IOCTL_IOW(LINUX_TCSETAW
, linux_ioctl_TCSETAW
, struct linux_termio
),
1184 MAPPED_IOCTL_IOW(LINUX_TCSETAF
, linux_ioctl_TCSETAF
, struct linux_termio
),
1185 MAPPED_IOCTL_IO(LINUX_TCXONC
, linux_ioctl_TCXONC
),
1186 MAPPED_IOCTL_IO(LINUX_TCFLSH
, linux_ioctl_TCFLSH
),
1187 MAPPED_IOCTL_MAP(LINUX_TIOCEXCL
, TIOCEXCL
),
1188 MAPPED_IOCTL_MAP(LINUX_TIOCNXCL
, TIOCNXCL
),
1189 MAPPED_IOCTL_MAP(LINUX_TIOCGPGRP
, TIOCGPGRP
),
1190 MAPPED_IOCTL_MAP(LINUX_TIOCSPGRP
, TIOCSPGRP
),
1191 MAPPED_IOCTL_MAP(LINUX_TIOCGWINSZ
, TIOCGWINSZ
),
1192 MAPPED_IOCTL_MAP(LINUX_TIOCSWINSZ
, TIOCSWINSZ
),
1193 MAPPED_IOCTL_MAP(LINUX_TIOCMGET
, TIOCMGET
),
1194 MAPPED_IOCTL_MAP(LINUX_TIOCMBIS
, TIOCMBIS
),
1195 MAPPED_IOCTL_MAP(LINUX_TIOCMBIC
, TIOCMBIC
),
1196 MAPPED_IOCTL_MAP(LINUX_TIOCMSET
, TIOCMSET
),
1197 MAPPED_IOCTL_MAP(LINUX_FIONREAD
, FIONREAD
),
1198 MAPPED_IOCTL_MAP(LINUX_TIOCCONS
, TIOCCONS
),
1199 MAPPED_IOCTL_IOR(LINUX_TIOCGSERIAL
, linux_ioctl_TIOCGSERIAL
, struct linux_serial_struct
),
1200 MAPPED_IOCTL_IOW(LINUX_TIOCSSERIAL
, linux_ioctl_TIOCSSERIAL
, struct linux_serial_struct
),
1201 MAPPED_IOCTL_MAP(LINUX_FIONBIO
, FIONBIO
),
1202 MAPPED_IOCTL_MAP(LINUX_TIOCNOTTY
, TIOCNOTTY
),
1203 MAPPED_IOCTL_IO(LINUX_TIOCSETD
, linux_ioctl_TIOCSETD
),
1204 MAPPED_IOCTL_IOR(LINUX_TIOCGETD
, linux_ioctl_TIOCGETD
, int),
1205 MAPPED_IOCTL_MAP(LINUX_FIONCLEX
, FIONCLEX
),
1206 MAPPED_IOCTL_MAP(LINUX_FIOCLEX
, FIOCLEX
),
1207 MAPPED_IOCTL_MAP(LINUX_FIOASYNC
, FIOASYNC
),
1209 MAPPED_IOCTL_MAP(LINUX_CDROMPAUSE
, CDIOCPAUSE
),
1210 MAPPED_IOCTL_MAP(LINUX_CDROMRESUME
, CDIOCRESUME
),
1211 MAPPED_IOCTL_MAP(LINUX_CDROMPLAYMSF
, CDIOCPLAYMSF
),
1212 MAPPED_IOCTL_MAP(LINUX_CDROMPLAYTRKIND
, CDIOCPLAYTRACKS
),
1213 MAPPED_IOCTL_IOR(LINUX_CDROMREADTOCHDR
, linux_ioctl_CDROMREADTOCHDR
, struct linux_cdrom_tochdr
),
1214 MAPPED_IOCTL_IOWR(LINUX_CDROMREADTOCENTRY
, linux_ioctl_CDROMREADTOCENTRY
, struct linux_cdrom_tocentry
),
1215 MAPPED_IOCTL_MAP(LINUX_CDROMSTOP
, CDIOCSTOP
),
1216 MAPPED_IOCTL_MAP(LINUX_CDROMSTART
, CDIOCSTART
),
1217 MAPPED_IOCTL_MAP(LINUX_CDROMEJECT
, CDIOCEJECT
),
1218 MAPPED_IOCTL_IOWR(LINUX_CDROMSUBCHNL
, linux_ioctl_CDROMSUBCHNL
, struct linux_cdrom_subchnl
),
1219 MAPPED_IOCTL_MAP(LINUX_CDROMRESET
, CDIOCRESET
),
1221 MAPPED_IOCTL_MAPRANGE(LINUX_SOUND_MIXER_WRITE_MIN
, LINUX_SOUND_MIXER_WRITE_MAX
,
1222 LINUX_SOUND_MIXER_WRITE_MIN
, LINUX_SOUND_MIXER_WRITE_MAX
,
1223 NULL
, linux_gen_dirmap
),
1224 MAPPED_IOCTL_IOR(LINUX_OSS_GETVERSION
, linux_ioctl_OSS_GETVERSION
, int),
1225 MAPPED_IOCTL_MAP(LINUX_SOUND_MIXER_READ_DEVMASK
, SOUND_MIXER_READ_DEVMASK
),
1226 MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_DSP_MIN
, LINUX_SNDCTL_DSP_MAX
, LINUX_SNDCTL_DSP_MIN
,
1227 LINUX_SNDCTL_DSP_MAX
, NULL
, linux_gen_dirmap
),
1228 MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_SEQ_MIN
, LINUX_SNDCTL_SEQ_MAX
, LINUX_SNDCTL_SEQ_MIN
,
1229 LINUX_SNDCTL_SEQ_MAX
, NULL
, linux_gen_dirmap
),
1231 MAPPED_IOCTL_MAP(LINUX_KIOCSOUND
, KIOCSOUND
),
1232 MAPPED_IOCTL_MAP(LINUX_KDMKTONE
, KDMKTONE
),
1233 MAPPED_IOCTL_MAP(LINUX_KDGETLED
, KDGETLED
),
1234 MAPPED_IOCTL_MAP(LINUX_KDSETLED
, KDSETLED
),
1235 MAPPED_IOCTL_MAP(LINUX_KDSETMODE
, KDSETMODE
),
1236 MAPPED_IOCTL_MAP(LINUX_KDGETMODE
, KDGETMODE
),
1237 MAPPED_IOCTL_MAP(LINUX_KDGKBMODE
, KDGKBMODE
),
1238 MAPPED_IOCTL_IOW(LINUX_KDSKBMODE
, linux_ioctl_KDSKBMODE
, int),
1239 MAPPED_IOCTL_MAP(LINUX_VT_OPENQRY
, VT_OPENQRY
),
1240 MAPPED_IOCTL_MAP(LINUX_VT_GETMODE
, VT_GETMODE
),
1241 MAPPED_IOCTL_IOW(LINUX_VT_SETMODE
, linux_ioctl_VT_SETMODE
, struct vt_mode
),
1242 MAPPED_IOCTL_MAP(LINUX_VT_GETSTATE
, VT_GETACTIVE
),
1243 MAPPED_IOCTL_MAP(LINUX_VT_RELDISP
, VT_RELDISP
),
1244 MAPPED_IOCTL_MAP(LINUX_VT_ACTIVATE
, VT_ACTIVATE
),
1245 MAPPED_IOCTL_MAP(LINUX_VT_WAITACTIVE
, VT_WAITACTIVE
),
1247 MAPPED_IOCTL_MAP(LINUX_FIOSETOWN
, FIOSETOWN
),
1248 MAPPED_IOCTL_MAP(LINUX_SIOCSPGRP
, SIOCSPGRP
),
1249 MAPPED_IOCTL_MAP(LINUX_FIOGETOWN
, FIOGETOWN
),
1250 MAPPED_IOCTL_MAP(LINUX_SIOCGPGRP
, SIOCGPGRP
),
1251 MAPPED_IOCTL_MAP(LINUX_SIOCATMARK
, SIOCATMARK
),
1252 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFCONF
, linux_ioctl_SIOCGIFCONF
, struct ifconf
),
1253 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFFLAGS
, linux_ioctl_SIOCGIFFLAGS
, struct l_ifreq
),
1254 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFADDR
, OSIOCGIFADDR
, linux_ioctl_map_ifname
),
1255 MAPPED_IOCTL_MAPF(LINUX_SIOCSIFADDR
, SIOCSIFADDR
, linux_ioctl_map_ifname
),
1256 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFDSTADDR
, OSIOCGIFDSTADDR
, linux_ioctl_map_ifname
),
1257 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFBRDADDR
, OSIOCGIFBRDADDR
, linux_ioctl_map_ifname
),
1258 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFNETMASK
, OSIOCGIFNETMASK
, linux_ioctl_map_ifname
),
1259 /*MAPPED_IOCTL_IOx(LINUX_SIOCSIFNETMASK, x, x),*/
1260 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFMTU
, SIOCGIFMTU
, linux_ioctl_map_ifname
),
1261 MAPPED_IOCTL_MAPF(LINUX_SIOCSIFMTU
, SIOCSIFMTU
, linux_ioctl_map_ifname
),
1262 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFHWADDR
, linux_ioctl_SIOGIFHWADDR
, struct l_ifreq
),
1263 MAPPED_IOCTL_MAP(LINUX_SIOCADDMULTI
, SIOCADDMULTI
),
1264 MAPPED_IOCTL_MAP(LINUX_SIOCDELMULTI
, SIOCDELMULTI
),
1266 * XXX This is slightly bogus, but these ioctls are currently
1267 * XXX only used by the aironet (if_an) network driver.
1269 MAPPED_IOCTL_MAPF(LINUX_SIOCDEVPRIVATE
, SIOCGPRIVATE_0
, linux_ioctl_map_ifname
),
1270 MAPPED_IOCTL_MAPF(LINUX_SIOCDEVPRIVATE
+1, SIOCGPRIVATE_1
, linux_ioctl_map_ifname
),
1271 MAPPED_IOCTL_MAPF(0, 0, NULL
)
1274 struct ioctl_map linux_ioctl_map
= {
1276 "linux", /* subsys */
1277 LIST_HEAD_INITIALIZER(mapping
)
1280 static struct ioctl_map_handler linux_ioctl_base_handler
= {
1283 linux_ioctl_map_entries
1287 * main ioctl syscall function
1291 sys_linux_ioctl(struct linux_ioctl_args
*args
)
1295 kprintf(ARGS(ioctl
, "%d, %04x, *"), args
->fd
, args
->cmd
);
1298 return (mapped_ioctl(args
->fd
, args
->cmd
, (caddr_t
)args
->arg
, &linux_ioctl_map
));
1301 SYSINIT (linux_ioctl_register
, SI_BOOT2_KLD
, SI_ORDER_MIDDLE
,
1302 mapped_ioctl_register_handler
, &linux_ioctl_base_handler
);
1303 SYSUNINIT(linux_ioctl_register
, SI_BOOT2_KLD
, SI_ORDER_MIDDLE
,
1304 mapped_ioctl_unregister_handler
, &linux_ioctl_base_handler
);