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>
44 #include <sys/ioccom.h>
46 #include <sys/kernel.h>
47 #include <sys/linker_set.h>
48 #include <sys/malloc.h>
49 #include <sys/mapped_ioctl.h>
51 #include <sys/socket.h>
52 #include <sys/sockio.h>
53 #include <sys/soundcard.h>
57 #include <net/if_dl.h>
58 #include <net/if_types.h>
59 #include <sys/file2.h>
61 #include <arch_linux/linux.h>
62 #include <arch_linux/linux_proto.h>
64 #include "linux_ioctl.h"
65 #include "linux_mib.h"
66 #include "linux_util.h"
70 linux_ioctl_BLKGETSIZE32(struct file
*fp
, u_long cmd
, u_long ocmd
,
71 caddr_t data
, struct ucred
*cred
)
73 struct partinfo dpart
;
77 error
= fo_ioctl(fp
, DIOCGPART
, (caddr_t
)&dpart
, cred
);
80 value
= dpart
.media_blocks
; /* 64->32 */
81 bcopy(&value
, data
, sizeof(value
));
87 * termio related ioctls
91 unsigned short c_iflag
;
92 unsigned short c_oflag
;
93 unsigned short c_cflag
;
94 unsigned short c_lflag
;
96 unsigned char c_cc
[LINUX_NCC
];
99 struct linux_termios
{
100 unsigned int c_iflag
;
101 unsigned int c_oflag
;
102 unsigned int c_cflag
;
103 unsigned int c_lflag
;
104 unsigned char c_line
;
105 unsigned char c_cc
[LINUX_NCCS
];
108 struct linux_winsize
{
109 unsigned short ws_row
, ws_col
;
110 unsigned short ws_xpixel
, ws_ypixel
;
113 static struct speedtab sptab
[] = {
114 { B0
, LINUX_B0
}, { B50
, LINUX_B50
},
115 { B75
, LINUX_B75
}, { B110
, LINUX_B110
},
116 { B134
, LINUX_B134
}, { B150
, LINUX_B150
},
117 { B200
, LINUX_B200
}, { B300
, LINUX_B300
},
118 { B600
, LINUX_B600
}, { B1200
, LINUX_B1200
},
119 { B1800
, LINUX_B1800
}, { B2400
, LINUX_B2400
},
120 { B4800
, LINUX_B4800
}, { B9600
, LINUX_B9600
},
121 { B19200
, LINUX_B19200
}, { B38400
, LINUX_B38400
},
122 { B57600
, LINUX_B57600
}, { B115200
, LINUX_B115200
},
126 struct linux_serial_struct
{
135 unsigned short close_delay
;
136 char reserved_char
[2];
138 unsigned short closing_wait
;
139 unsigned short closing_wait2
;
144 linux_to_bsd_speed(int code
, struct speedtab
*table
)
146 for ( ; table
->sp_code
!= -1; table
++)
147 if (table
->sp_code
== code
)
148 return (table
->sp_speed
);
153 bsd_to_linux_speed(int speed
, struct speedtab
*table
)
155 for ( ; table
->sp_speed
!= -1; table
++)
156 if (table
->sp_speed
== speed
)
157 return (table
->sp_code
);
162 bsd_to_linux_termios(struct termios
*bios
, struct linux_termios
*lios
)
168 kprintf("LINUX: BSD termios structure (input):\n");
169 kprintf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
170 bios
->c_iflag
, bios
->c_oflag
, bios
->c_cflag
, bios
->c_lflag
,
171 bios
->c_ispeed
, bios
->c_ospeed
);
173 for (i
=0; i
<NCCS
; i
++)
174 kprintf("%02x ", bios
->c_cc
[i
]);
180 if (bios
->c_iflag
& IGNBRK
)
181 lios
->c_iflag
|= LINUX_IGNBRK
;
182 if (bios
->c_iflag
& BRKINT
)
183 lios
->c_iflag
|= LINUX_BRKINT
;
184 if (bios
->c_iflag
& IGNPAR
)
185 lios
->c_iflag
|= LINUX_IGNPAR
;
186 if (bios
->c_iflag
& PARMRK
)
187 lios
->c_iflag
|= LINUX_PARMRK
;
188 if (bios
->c_iflag
& INPCK
)
189 lios
->c_iflag
|= LINUX_INPCK
;
190 if (bios
->c_iflag
& ISTRIP
)
191 lios
->c_iflag
|= LINUX_ISTRIP
;
192 if (bios
->c_iflag
& INLCR
)
193 lios
->c_iflag
|= LINUX_INLCR
;
194 if (bios
->c_iflag
& IGNCR
)
195 lios
->c_iflag
|= LINUX_IGNCR
;
196 if (bios
->c_iflag
& ICRNL
)
197 lios
->c_iflag
|= LINUX_ICRNL
;
198 if (bios
->c_iflag
& IXON
)
199 lios
->c_iflag
|= LINUX_IXON
;
200 if (bios
->c_iflag
& IXANY
)
201 lios
->c_iflag
|= LINUX_IXANY
;
202 if (bios
->c_iflag
& IXOFF
)
203 lios
->c_iflag
|= LINUX_IXOFF
;
204 if (bios
->c_iflag
& IMAXBEL
)
205 lios
->c_iflag
|= LINUX_IMAXBEL
;
208 if (bios
->c_oflag
& OPOST
)
209 lios
->c_oflag
|= LINUX_OPOST
;
210 if (bios
->c_oflag
& ONLCR
)
211 lios
->c_oflag
|= LINUX_ONLCR
;
212 if (bios
->c_oflag
& OXTABS
)
213 lios
->c_oflag
|= LINUX_XTABS
;
215 lios
->c_cflag
= bsd_to_linux_speed(bios
->c_ispeed
, sptab
);
216 lios
->c_cflag
|= (bios
->c_cflag
& CSIZE
) >> 4;
217 if (bios
->c_cflag
& CSTOPB
)
218 lios
->c_cflag
|= LINUX_CSTOPB
;
219 if (bios
->c_cflag
& CREAD
)
220 lios
->c_cflag
|= LINUX_CREAD
;
221 if (bios
->c_cflag
& PARENB
)
222 lios
->c_cflag
|= LINUX_PARENB
;
223 if (bios
->c_cflag
& PARODD
)
224 lios
->c_cflag
|= LINUX_PARODD
;
225 if (bios
->c_cflag
& HUPCL
)
226 lios
->c_cflag
|= LINUX_HUPCL
;
227 if (bios
->c_cflag
& CLOCAL
)
228 lios
->c_cflag
|= LINUX_CLOCAL
;
229 if (bios
->c_cflag
& CRTSCTS
)
230 lios
->c_cflag
|= LINUX_CRTSCTS
;
233 if (bios
->c_lflag
& ISIG
)
234 lios
->c_lflag
|= LINUX_ISIG
;
235 if (bios
->c_lflag
& ICANON
)
236 lios
->c_lflag
|= LINUX_ICANON
;
237 if (bios
->c_lflag
& ECHO
)
238 lios
->c_lflag
|= LINUX_ECHO
;
239 if (bios
->c_lflag
& ECHOE
)
240 lios
->c_lflag
|= LINUX_ECHOE
;
241 if (bios
->c_lflag
& ECHOK
)
242 lios
->c_lflag
|= LINUX_ECHOK
;
243 if (bios
->c_lflag
& ECHONL
)
244 lios
->c_lflag
|= LINUX_ECHONL
;
245 if (bios
->c_lflag
& NOFLSH
)
246 lios
->c_lflag
|= LINUX_NOFLSH
;
247 if (bios
->c_lflag
& TOSTOP
)
248 lios
->c_lflag
|= LINUX_TOSTOP
;
249 if (bios
->c_lflag
& ECHOCTL
)
250 lios
->c_lflag
|= LINUX_ECHOCTL
;
251 if (bios
->c_lflag
& ECHOPRT
)
252 lios
->c_lflag
|= LINUX_ECHOPRT
;
253 if (bios
->c_lflag
& ECHOKE
)
254 lios
->c_lflag
|= LINUX_ECHOKE
;
255 if (bios
->c_lflag
& FLUSHO
)
256 lios
->c_lflag
|= LINUX_FLUSHO
;
257 if (bios
->c_lflag
& PENDIN
)
258 lios
->c_lflag
|= LINUX_PENDIN
;
259 if (bios
->c_lflag
& IEXTEN
)
260 lios
->c_lflag
|= LINUX_IEXTEN
;
262 for (i
=0; i
<LINUX_NCCS
; i
++)
263 lios
->c_cc
[i
] = LINUX_POSIX_VDISABLE
;
264 lios
->c_cc
[LINUX_VINTR
] = bios
->c_cc
[VINTR
];
265 lios
->c_cc
[LINUX_VQUIT
] = bios
->c_cc
[VQUIT
];
266 lios
->c_cc
[LINUX_VERASE
] = bios
->c_cc
[VERASE
];
267 lios
->c_cc
[LINUX_VKILL
] = bios
->c_cc
[VKILL
];
268 lios
->c_cc
[LINUX_VEOF
] = bios
->c_cc
[VEOF
];
269 lios
->c_cc
[LINUX_VEOL
] = bios
->c_cc
[VEOL
];
270 lios
->c_cc
[LINUX_VMIN
] = bios
->c_cc
[VMIN
];
271 lios
->c_cc
[LINUX_VTIME
] = bios
->c_cc
[VTIME
];
272 lios
->c_cc
[LINUX_VEOL2
] = bios
->c_cc
[VEOL2
];
273 lios
->c_cc
[LINUX_VSUSP
] = bios
->c_cc
[VSUSP
];
274 lios
->c_cc
[LINUX_VSTART
] = bios
->c_cc
[VSTART
];
275 lios
->c_cc
[LINUX_VSTOP
] = bios
->c_cc
[VSTOP
];
276 lios
->c_cc
[LINUX_VREPRINT
] = bios
->c_cc
[VREPRINT
];
277 lios
->c_cc
[LINUX_VDISCARD
] = bios
->c_cc
[VDISCARD
];
278 lios
->c_cc
[LINUX_VWERASE
] = bios
->c_cc
[VWERASE
];
279 lios
->c_cc
[LINUX_VLNEXT
] = bios
->c_cc
[VLNEXT
];
281 for (i
=0; i
<LINUX_NCCS
; i
++) {
282 if (i
!= LINUX_VMIN
&& i
!= LINUX_VTIME
&&
283 lios
->c_cc
[i
] == _POSIX_VDISABLE
)
284 lios
->c_cc
[i
] = LINUX_POSIX_VDISABLE
;
290 kprintf("LINUX: LINUX termios structure (output):\n");
291 kprintf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
292 lios
->c_iflag
, lios
->c_oflag
, lios
->c_cflag
,
293 lios
->c_lflag
, (int)lios
->c_line
);
295 for (i
=0; i
<LINUX_NCCS
; i
++)
296 kprintf("%02x ", lios
->c_cc
[i
]);
303 linux_to_bsd_termios(struct linux_termios
*lios
, struct termios
*bios
)
309 kprintf("LINUX: LINUX termios structure (input):\n");
310 kprintf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
311 lios
->c_iflag
, lios
->c_oflag
, lios
->c_cflag
,
312 lios
->c_lflag
, (int)lios
->c_line
);
314 for (i
=0; i
<LINUX_NCCS
; i
++)
315 kprintf("%02x ", lios
->c_cc
[i
]);
321 if (lios
->c_iflag
& LINUX_IGNBRK
)
322 bios
->c_iflag
|= IGNBRK
;
323 if (lios
->c_iflag
& LINUX_BRKINT
)
324 bios
->c_iflag
|= BRKINT
;
325 if (lios
->c_iflag
& LINUX_IGNPAR
)
326 bios
->c_iflag
|= IGNPAR
;
327 if (lios
->c_iflag
& LINUX_PARMRK
)
328 bios
->c_iflag
|= PARMRK
;
329 if (lios
->c_iflag
& LINUX_INPCK
)
330 bios
->c_iflag
|= INPCK
;
331 if (lios
->c_iflag
& LINUX_ISTRIP
)
332 bios
->c_iflag
|= ISTRIP
;
333 if (lios
->c_iflag
& LINUX_INLCR
)
334 bios
->c_iflag
|= INLCR
;
335 if (lios
->c_iflag
& LINUX_IGNCR
)
336 bios
->c_iflag
|= IGNCR
;
337 if (lios
->c_iflag
& LINUX_ICRNL
)
338 bios
->c_iflag
|= ICRNL
;
339 if (lios
->c_iflag
& LINUX_IXON
)
340 bios
->c_iflag
|= IXON
;
341 if (lios
->c_iflag
& LINUX_IXANY
)
342 bios
->c_iflag
|= IXANY
;
343 if (lios
->c_iflag
& LINUX_IXOFF
)
344 bios
->c_iflag
|= IXOFF
;
345 if (lios
->c_iflag
& LINUX_IMAXBEL
)
346 bios
->c_iflag
|= IMAXBEL
;
349 if (lios
->c_oflag
& LINUX_OPOST
)
350 bios
->c_oflag
|= OPOST
;
351 if (lios
->c_oflag
& LINUX_ONLCR
)
352 bios
->c_oflag
|= ONLCR
;
353 if (lios
->c_oflag
& LINUX_XTABS
)
354 bios
->c_oflag
|= OXTABS
;
356 bios
->c_cflag
= (lios
->c_cflag
& LINUX_CSIZE
) << 4;
357 if (lios
->c_cflag
& LINUX_CSTOPB
)
358 bios
->c_cflag
|= CSTOPB
;
359 if (lios
->c_cflag
& LINUX_CREAD
)
360 bios
->c_cflag
|= CREAD
;
361 if (lios
->c_cflag
& LINUX_PARENB
)
362 bios
->c_cflag
|= PARENB
;
363 if (lios
->c_cflag
& LINUX_PARODD
)
364 bios
->c_cflag
|= PARODD
;
365 if (lios
->c_cflag
& LINUX_HUPCL
)
366 bios
->c_cflag
|= HUPCL
;
367 if (lios
->c_cflag
& LINUX_CLOCAL
)
368 bios
->c_cflag
|= CLOCAL
;
369 if (lios
->c_cflag
& LINUX_CRTSCTS
)
370 bios
->c_cflag
|= CRTSCTS
;
373 if (lios
->c_lflag
& LINUX_ISIG
)
374 bios
->c_lflag
|= ISIG
;
375 if (lios
->c_lflag
& LINUX_ICANON
)
376 bios
->c_lflag
|= ICANON
;
377 if (lios
->c_lflag
& LINUX_ECHO
)
378 bios
->c_lflag
|= ECHO
;
379 if (lios
->c_lflag
& LINUX_ECHOE
)
380 bios
->c_lflag
|= ECHOE
;
381 if (lios
->c_lflag
& LINUX_ECHOK
)
382 bios
->c_lflag
|= ECHOK
;
383 if (lios
->c_lflag
& LINUX_ECHONL
)
384 bios
->c_lflag
|= ECHONL
;
385 if (lios
->c_lflag
& LINUX_NOFLSH
)
386 bios
->c_lflag
|= NOFLSH
;
387 if (lios
->c_lflag
& LINUX_TOSTOP
)
388 bios
->c_lflag
|= TOSTOP
;
389 if (lios
->c_lflag
& LINUX_ECHOCTL
)
390 bios
->c_lflag
|= ECHOCTL
;
391 if (lios
->c_lflag
& LINUX_ECHOPRT
)
392 bios
->c_lflag
|= ECHOPRT
;
393 if (lios
->c_lflag
& LINUX_ECHOKE
)
394 bios
->c_lflag
|= ECHOKE
;
395 if (lios
->c_lflag
& LINUX_FLUSHO
)
396 bios
->c_lflag
|= FLUSHO
;
397 if (lios
->c_lflag
& LINUX_PENDIN
)
398 bios
->c_lflag
|= PENDIN
;
399 if (lios
->c_lflag
& LINUX_IEXTEN
)
400 bios
->c_lflag
|= IEXTEN
;
402 for (i
=0; i
<NCCS
; i
++)
403 bios
->c_cc
[i
] = _POSIX_VDISABLE
;
404 bios
->c_cc
[VINTR
] = lios
->c_cc
[LINUX_VINTR
];
405 bios
->c_cc
[VQUIT
] = lios
->c_cc
[LINUX_VQUIT
];
406 bios
->c_cc
[VERASE
] = lios
->c_cc
[LINUX_VERASE
];
407 bios
->c_cc
[VKILL
] = lios
->c_cc
[LINUX_VKILL
];
408 bios
->c_cc
[VEOF
] = lios
->c_cc
[LINUX_VEOF
];
409 bios
->c_cc
[VEOL
] = lios
->c_cc
[LINUX_VEOL
];
410 bios
->c_cc
[VMIN
] = lios
->c_cc
[LINUX_VMIN
];
411 bios
->c_cc
[VTIME
] = lios
->c_cc
[LINUX_VTIME
];
412 bios
->c_cc
[VEOL2
] = lios
->c_cc
[LINUX_VEOL2
];
413 bios
->c_cc
[VSUSP
] = lios
->c_cc
[LINUX_VSUSP
];
414 bios
->c_cc
[VSTART
] = lios
->c_cc
[LINUX_VSTART
];
415 bios
->c_cc
[VSTOP
] = lios
->c_cc
[LINUX_VSTOP
];
416 bios
->c_cc
[VREPRINT
] = lios
->c_cc
[LINUX_VREPRINT
];
417 bios
->c_cc
[VDISCARD
] = lios
->c_cc
[LINUX_VDISCARD
];
418 bios
->c_cc
[VWERASE
] = lios
->c_cc
[LINUX_VWERASE
];
419 bios
->c_cc
[VLNEXT
] = lios
->c_cc
[LINUX_VLNEXT
];
421 for (i
=0; i
<NCCS
; i
++) {
422 if (i
!= VMIN
&& i
!= VTIME
&&
423 bios
->c_cc
[i
] == LINUX_POSIX_VDISABLE
)
424 bios
->c_cc
[i
] = _POSIX_VDISABLE
;
427 bios
->c_ispeed
= bios
->c_ospeed
=
428 linux_to_bsd_speed(lios
->c_cflag
& LINUX_CBAUD
, sptab
);
432 kprintf("LINUX: BSD termios structure (output):\n");
433 kprintf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
434 bios
->c_iflag
, bios
->c_oflag
, bios
->c_cflag
, bios
->c_lflag
,
435 bios
->c_ispeed
, bios
->c_ospeed
);
437 for (i
=0; i
<NCCS
; i
++)
438 kprintf("%02x ", bios
->c_cc
[i
]);
445 bsd_to_linux_termio(struct termios
*bios
, struct linux_termio
*lio
)
447 struct linux_termios lios
;
449 bsd_to_linux_termios(bios
, &lios
);
450 lio
->c_iflag
= lios
.c_iflag
;
451 lio
->c_oflag
= lios
.c_oflag
;
452 lio
->c_cflag
= lios
.c_cflag
;
453 lio
->c_lflag
= lios
.c_lflag
;
454 lio
->c_line
= lios
.c_line
;
455 memcpy(lio
->c_cc
, lios
.c_cc
, LINUX_NCC
);
459 linux_to_bsd_termio(struct linux_termio
*lio
, struct termios
*bios
)
461 struct linux_termios lios
;
464 lios
.c_iflag
= lio
->c_iflag
;
465 lios
.c_oflag
= lio
->c_oflag
;
466 lios
.c_cflag
= lio
->c_cflag
;
467 lios
.c_lflag
= lio
->c_lflag
;
468 for (i
=LINUX_NCC
; i
<LINUX_NCCS
; i
++)
469 lios
.c_cc
[i
] = LINUX_POSIX_VDISABLE
;
470 memcpy(lios
.c_cc
, lio
->c_cc
, LINUX_NCC
);
471 linux_to_bsd_termios(&lios
, bios
);
475 linux_ioctl_TCGETS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
478 struct linux_termios lios
;
481 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
);
484 bsd_to_linux_termios(&bios
, &lios
);
485 bcopy(&lios
, data
, sizeof(lios
));
490 linux_ioctl_TCSETS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
493 struct linux_termios lios
;
495 bcopy(data
, &lios
, sizeof(lios
));
496 linux_to_bsd_termios(&lios
, &bios
);
497 return (fo_ioctl(fp
, TIOCSETA
, (caddr_t
)&bios
, cred
));
501 linux_ioctl_TCSETSW(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
504 struct linux_termios lios
;
506 bcopy(data
, &lios
, sizeof(lios
));
507 linux_to_bsd_termios(&lios
, &bios
);
508 return (fo_ioctl(fp
, TIOCSETAW
, (caddr_t
)&bios
, cred
));
512 linux_ioctl_TCSETSF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
515 struct linux_termios lios
;
517 bcopy(data
, &lios
, sizeof(lios
));
518 linux_to_bsd_termios(&lios
, &bios
);
519 return (fo_ioctl(fp
, TIOCSETAF
, (caddr_t
)&bios
, cred
));
523 linux_ioctl_TCGETA(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
526 struct linux_termio lio
;
529 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
);
532 bsd_to_linux_termio(&bios
, &lio
);
533 bcopy(&lio
, data
, sizeof(lio
));
538 linux_ioctl_TCSETA(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
541 struct linux_termio lio
;
543 bcopy(data
, &lio
, sizeof(lio
));
544 linux_to_bsd_termio(&lio
, &bios
);
545 return (fo_ioctl(fp
, TIOCSETA
, (caddr_t
)&bios
, cred
));
549 linux_ioctl_TCSETAW(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
552 struct linux_termio lio
;
554 bcopy(data
, &lio
, sizeof(lio
));
555 linux_to_bsd_termio(&lio
, &bios
);
556 return (fo_ioctl(fp
, TIOCSETAW
, (caddr_t
)&bios
, cred
));
560 linux_ioctl_TCSETAF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
563 struct linux_termio lio
;
565 bcopy(data
, &lio
, sizeof(lio
));
566 linux_to_bsd_termio(&lio
, &bios
);
567 return (fo_ioctl(fp
, TIOCSETAF
, (caddr_t
)&bios
, cred
));
571 linux_ioctl_TCXONC(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
573 switch ((u_long
)data
) {
585 error
= fo_ioctl(fp
, TIOCGETA
, (caddr_t
)&bios
, cred
);
588 c
= ((u_long
)data
== LINUX_TCIOFF
) ? VSTOP
: VSTART
;
590 if (c
!= _POSIX_VDISABLE
) {
594 aiov
.iov_base
= (char *)&c
;
595 aiov
.iov_len
= sizeof(*bios
.c_cc
);
596 auio
.uio_iov
= &aiov
;
598 auio
.uio_offset
= -1;
599 auio
.uio_resid
= sizeof(*bios
.c_cc
);
600 auio
.uio_rw
= UIO_WRITE
;
601 auio
.uio_segflg
= UIO_SYSSPACE
;
602 auio
.uio_td
= curthread
;
604 return (fo_write(fp
, &auio
, fp
->f_cred
, 0));
612 return (fo_ioctl(fp
, cmd
, 0, cred
));
616 linux_ioctl_TCFLSH(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
618 switch ((u_long
)data
) {
620 *(u_long
*)data
= FREAD
;
623 *(u_long
*)data
= FWRITE
;
625 case LINUX_TCIOFLUSH
:
626 *(u_long
*)data
= FREAD
| FWRITE
;
631 return (fo_ioctl(fp
, TIOCFLUSH
, data
, cred
));
635 linux_ioctl_TIOCGSERIAL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
637 struct linux_serial_struct lss
;
639 lss
.type
= LINUX_PORT_16550A
;
642 bcopy(&lss
, data
, sizeof(lss
));
647 linux_ioctl_TIOCSSERIAL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
650 struct linux_serial_struct lss
;
652 bcopy(data
, &lss
, sizeof(lss
));
653 /* XXX - It really helps to have an implementation that
661 linux_ioctl_TIOCSETD(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
665 switch ((u_long
)data
) {
678 return (fo_ioctl(fp
, TIOCSETD
, (caddr_t
)&line
, cred
));
682 linux_ioctl_TIOCGETD(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
684 int linux_line
, error
;
685 int bsd_line
= TTYDISC
;
687 error
= fo_ioctl(fp
, TIOCGETD
, (caddr_t
)&bsd_line
, cred
);
692 linux_line
= LINUX_N_TTY
;
695 linux_line
= LINUX_N_SLIP
;
698 linux_line
= LINUX_N_PPP
;
703 bcopy(&linux_line
, data
, sizeof(int));
709 * CDROM related ioctls
712 struct linux_cdrom_msf
722 struct linux_cdrom_tochdr
728 union linux_cdrom_addr
738 struct linux_cdrom_tocentry
744 union linux_cdrom_addr cdte_addr
;
745 u_char cdte_datamode
;
748 struct linux_cdrom_subchnl
751 u_char cdsc_audiostatus
;
756 union linux_cdrom_addr cdsc_absaddr
;
757 union linux_cdrom_addr cdsc_reladdr
;
761 bsd_to_linux_msf_lba(u_char af
, union msf_lba
*bp
, union linux_cdrom_addr
*lp
)
763 if (af
== CD_LBA_FORMAT
)
766 lp
->msf
.minute
= bp
->msf
.minute
;
767 lp
->msf
.second
= bp
->msf
.second
;
768 lp
->msf
.frame
= bp
->msf
.frame
;
773 set_linux_cdrom_addr(union linux_cdrom_addr
*addr
, int format
, int lba
)
775 if (format
== LINUX_CDROM_MSF
) {
776 addr
->msf
.frame
= lba
% 75;
779 addr
->msf
.second
= lba
% 60;
780 addr
->msf
.minute
= lba
/ 60;
786 linux_ioctl_CDROMREADTOCHDR(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
788 struct ioc_toc_header th
;
789 struct linux_cdrom_tochdr lth
;
792 error
= fo_ioctl(fp
, CDIOREADTOCHEADER
, (caddr_t
)&th
, cred
);
795 lth
.cdth_trk0
= th
.starting_track
;
796 lth
.cdth_trk1
= th
.ending_track
;
797 bcopy(<h
, data
, sizeof(lth
));
802 linux_ioctl_CDROMREADTOCENTRY(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
804 struct linux_cdrom_tocentry
*ltep
= (struct linux_cdrom_tocentry
*)data
;
805 struct ioc_read_toc_single_entry irtse
;
808 irtse
.address_format
= ltep
->cdte_format
;
809 irtse
.track
= ltep
->cdte_track
;
810 error
= fo_ioctl(fp
, CDIOREADTOCENTRY
, (caddr_t
)&irtse
, cred
);
814 ltep
->cdte_ctrl
= irtse
.entry
.control
;
815 ltep
->cdte_adr
= irtse
.entry
.addr_type
;
816 bsd_to_linux_msf_lba(irtse
.address_format
, &irtse
.entry
.addr
,
822 linux_ioctl_CDROMSUBCHNL(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
824 struct linux_cdrom_subchnl
*sc
= (struct linux_cdrom_subchnl
*)data
;
825 struct ioc_read_subchannel bsdsc
;
826 struct cd_sub_channel_info
*bsdinfo
;
828 caddr_t sg
= stackgap_init();
830 bsdinfo
= stackgap_alloc(&sg
, sizeof(struct cd_sub_channel_info
));
831 bsdsc
.address_format
= CD_LBA_FORMAT
;
832 bsdsc
.data_format
= CD_CURRENT_POSITION
;
834 bsdsc
.data_len
= sizeof(struct cd_sub_channel_info
);
835 bsdsc
.data
= bsdinfo
;
836 error
= fo_ioctl(fp
, CDIOCREADSUBCHANNEL
, (caddr_t
)&bsdsc
, cred
);
839 sc
->cdsc_audiostatus
= bsdinfo
->header
.audio_status
;
840 sc
->cdsc_adr
= bsdinfo
->what
.position
.addr_type
;
841 sc
->cdsc_ctrl
= bsdinfo
->what
.position
.control
;
842 sc
->cdsc_trk
= bsdinfo
->what
.position
.track_number
;
843 sc
->cdsc_ind
= bsdinfo
->what
.position
.index_number
;
844 set_linux_cdrom_addr(&sc
->cdsc_absaddr
, sc
->cdsc_format
, bsdinfo
->what
.position
.absaddr
.lba
);
845 set_linux_cdrom_addr(&sc
->cdsc_reladdr
, sc
->cdsc_format
, bsdinfo
->what
.position
.reladdr
.lba
);
851 * Sound related ioctls
855 linux_ioctl_OSS_GETVERSION(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
857 int version
= linux_get_oss_version(curthread
);
859 bcopy(&version
, data
, sizeof(int));
865 * Console related ioctls
868 #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
871 linux_ioctl_KDSKBMODE(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
875 switch ((u_long
)data
) {
879 case LINUX_KBD_XLATE
:
882 case LINUX_KBD_MEDIUMRAW
:
888 return (fo_ioctl(fp
, KDSKBMODE
, (caddr_t
)&kbdmode
, cred
));
892 linux_ioctl_VT_SETMODE(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
894 struct vt_mode
*mode
= (struct vt_mode
*)data
;
896 if (!ISSIGVALID(mode
->frsig
) && ISSIGVALID(mode
->acqsig
))
897 mode
->frsig
= mode
->acqsig
;
898 return (fo_ioctl(fp
, VT_SETMODE
, data
, cred
));
903 * Socket related ioctls
907 * Criteria for interface name translation
909 #define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
912 * Interface function used by linprocfs (at the time of writing). It's not
913 * used by the Linuxulator itself.
916 linux_ifname(struct ifnet
*ifp
, char *buffer
, size_t buflen
)
918 struct ifnet
*ifscan
;
921 /* Short-circuit non ethernet interfaces */
922 if (!IFP_IS_ETH(ifp
))
923 return (strlcpy(buffer
, ifp
->if_xname
, buflen
));
925 /* Determine the (relative) unit number for ethernet interfaces */
927 TAILQ_FOREACH(ifscan
, &ifnet
, if_link
) {
929 return (ksnprintf(buffer
, buflen
, "eth%d", ethno
));
930 if (IFP_IS_ETH(ifscan
))
938 * Translate a Linux interface name to a FreeBSD interface name,
939 * and return the associated ifnet structure
940 * bsdname and lxname need to be least IFNAMSIZ bytes long, but
941 * can point to the same buffer.
944 static struct ifnet
*
945 ifname_linux_to_bsd(const char *lxname
, char *bsdname
)
952 for (len
= 0; len
< LINUX_IFNAMSIZ
; ++len
)
953 if (!isalpha(lxname
[len
]))
955 if (len
== 0 || len
== LINUX_IFNAMSIZ
)
957 unit
= (int)strtoul(lxname
+ len
, &ep
, 10);
958 if (ep
== NULL
|| ep
== lxname
+ len
|| ep
>= lxname
+ LINUX_IFNAMSIZ
)
961 is_eth
= (len
== 3 && !strncmp(lxname
, "eth", len
)) ? 1 : 0;
962 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
964 * Allow Linux programs to use FreeBSD names. Don't presume
965 * we never have an interface named "eth", so don't make
966 * the test optional based on is_eth.
968 if (strncmp(ifp
->if_xname
, lxname
, LINUX_IFNAMSIZ
) == 0)
970 if (is_eth
&& IFP_IS_ETH(ifp
) && unit
== index
++)
974 strlcpy(bsdname
, ifp
->if_xname
, IFNAMSIZ
);
979 linux_ioctl_SIOCGIFCONF(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
981 struct ifconf
*ifc
= (struct ifconf
*)data
;
988 /* much easier to use uiomove than keep track ourselves */
989 iov
.iov_base
= ifc
->ifc_buf
;
990 iov
.iov_len
= ifc
->ifc_len
;
994 uio
.uio_resid
= ifc
->ifc_len
;
995 uio
.uio_segflg
= UIO_USERSPACE
;
996 uio
.uio_rw
= UIO_READ
;
997 uio
.uio_td
= curthread
;
999 /* Keep track of eth interfaces */
1002 /* Return all AF_INET addresses of all interfaces */
1003 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
1004 struct ifaddr_container
*ifac
;
1006 if (uio
.uio_resid
<= 0)
1009 bzero(&ifr
, sizeof ifr
);
1010 if (IFP_IS_ETH(ifp
))
1011 ksnprintf(ifr
.ifr_name
, LINUX_IFNAMSIZ
, "eth%d",
1014 strlcpy(ifr
.ifr_name
, ifp
->if_xname
, LINUX_IFNAMSIZ
);
1016 /* Walk the address list */
1017 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1018 struct ifaddr
*ifa
= ifac
->ifa
;
1019 struct sockaddr
*sa
= ifa
->ifa_addr
;
1021 if (uio
.uio_resid
<= 0)
1024 if (sa
->sa_family
== AF_INET
) {
1025 ifr
.ifr_addr
.sa_family
= LINUX_AF_INET
;
1026 memcpy(ifr
.ifr_addr
.sa_data
, sa
->sa_data
,
1027 sizeof(ifr
.ifr_addr
.sa_data
));
1029 error
= uiomove((caddr_t
)&ifr
, sizeof ifr
,
1037 ifc
->ifc_len
-= uio
.uio_resid
;
1043 linux_ioctl_SIOCGIFFLAGS(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1045 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1047 char ifname
[IFNAMSIZ
];
1050 if (fp
->f_type
!= DTYPE_SOCKET
) {
1051 /* XXX: I doubt this is correct because
1052 * we don't translate the ifname and
1053 * use l_ifreq instead of ifreq
1055 return (fo_ioctl(fp
, SIOCGIFFLAGS
, data
, cred
));
1058 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1059 flags
= ifp
->if_flags
;
1060 /* these flags have no Linux equivalent */
1061 flags
&= ~(IFF_SMART
|IFF_OACTIVE
|IFF_SIMPLEX
|
1062 IFF_LINK0
|IFF_LINK1
|IFF_LINK2
);
1063 /* Linux' multicast flag is in a different bit */
1064 if (flags
& IFF_MULTICAST
) {
1065 flags
&= ~IFF_MULTICAST
;
1069 ifr
->ifr_flags
= flags
;
1073 #define ARPHRD_ETHER 1
1074 #define ARPHRD_LOOPBACK 772
1077 linux_ioctl_SIOGIFHWADDR(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1079 struct l_ifreq
*ifr
= (struct l_ifreq
*)data
;
1081 char ifname
[IFNAMSIZ
];
1082 struct sockaddr_dl
*sdl
;
1083 struct l_sockaddr lsa
;
1084 struct ifaddr_container
*ifac
;
1086 ifp
= ifname_linux_to_bsd(ifr
->ifr_name
, ifname
);
1087 if (ifp
->if_type
== IFT_LOOP
) {
1088 bzero(&ifr
->ifr_hwaddr
, sizeof lsa
);
1089 ifr
->ifr_hwaddr
.sa_family
= ARPHRD_LOOPBACK
;
1093 if (ifp
->if_type
!= IFT_ETHER
)
1096 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1097 struct ifaddr
*ifa
= ifac
->ifa
;
1099 sdl
= (struct sockaddr_dl
*)ifa
->ifa_addr
;
1100 if (sdl
!= NULL
&& (sdl
->sdl_family
== AF_LINK
) &&
1101 (sdl
->sdl_type
== IFT_ETHER
)) {
1102 bzero(&ifr
->ifr_hwaddr
, sizeof lsa
);
1103 ifr
->ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
1104 bcopy(LLADDR(sdl
), ifr
->ifr_hwaddr
.sa_data
, LINUX_IFHWADDRLEN
);
1113 linux_ioctl_map_ifname(struct file
*fp
, u_long cmd
, u_long ocmd
, caddr_t data
, struct ucred
*cred
)
1117 char *oifname
= (char *)data
;
1118 char lifname
[LINUX_IFNAMSIZ
];
1120 KASSERT(LINUX_IFNAMSIZ
== IFNAMSIZ
,
1121 ("%s(): LINUX_IFNAMSIZ != IFNAMSIZ", __func__
));
1123 if (fp
->f_type
!= DTYPE_SOCKET
) {
1125 * XXX: I doubt this is correct because
1126 * we don't map the ifname
1128 /* not a socket - probably a tap / vmnet device */
1129 if (ocmd
== LINUX_SIOCGIFADDR
|| ocmd
== LINUX_SIOCSIFADDR
) {
1130 cmd
= (ocmd
== LINUX_SIOCGIFADDR
) ? SIOCGIFADDR
: SIOCSIFADDR
;
1131 return (fo_ioctl(fp
, cmd
, data
, cred
));
1136 /* Save the original ifname */
1137 bcopy(oifname
, lifname
, LINUX_IFNAMSIZ
);
1139 kprintf("%s(): ioctl %d on %.*s\n", __func__
,
1140 (int)(cmd
& 0xffff), LINUX_IFNAMSIZ
, lifname
);
1142 /* Replace linux ifname with bsd ifname */
1143 ifp
= ifname_linux_to_bsd(lifname
, oifname
);
1150 kprintf("%s(): %s translated to %s\n", __func__
,
1154 error
= fo_ioctl(fp
, cmd
, data
, cred
);
1157 bcopy(lifname
, oifname
, LINUX_IFNAMSIZ
);
1163 * generic linux -> BSD syscall direction mapper
1166 linux_gen_dirmap(u_long lstart
, u_long lend
, u_long bstart
, u_long bend
, u_long cmd
, u_long ocmd
)
1168 static u_int32_t dirbits
[4] = { IOC_VOID
, IOC_IN
, IOC_OUT
, IOC_INOUT
};
1170 return ((cmd
& ~IOC_DIRMASK
) | dirbits
[ocmd
>> 30]);
1174 static struct ioctl_map_range linux_ioctl_map_entries
[] = {
1176 MAPPED_IOCTL_IOR(LINUX_BLKGETSIZE
, linux_ioctl_BLKGETSIZE32
, uint32_t),
1178 MAPPED_IOCTL_IOR(LINUX_TCGETS
, linux_ioctl_TCGETS
, struct linux_termios
),
1179 MAPPED_IOCTL_IOW(LINUX_TCSETS
, linux_ioctl_TCSETS
, struct linux_termios
),
1180 MAPPED_IOCTL_IOW(LINUX_TCSETSW
, linux_ioctl_TCSETSW
, struct linux_termios
),
1181 MAPPED_IOCTL_IOW(LINUX_TCSETSF
, linux_ioctl_TCSETSF
, struct linux_termios
),
1182 MAPPED_IOCTL_IOR(LINUX_TCGETA
, linux_ioctl_TCGETA
, struct linux_termio
),
1183 MAPPED_IOCTL_IOW(LINUX_TCSETA
, linux_ioctl_TCSETA
, struct linux_termio
),
1184 MAPPED_IOCTL_IOW(LINUX_TCSETAW
, linux_ioctl_TCSETAW
, struct linux_termio
),
1185 MAPPED_IOCTL_IOW(LINUX_TCSETAF
, linux_ioctl_TCSETAF
, struct linux_termio
),
1186 MAPPED_IOCTL_IO(LINUX_TCXONC
, linux_ioctl_TCXONC
),
1187 MAPPED_IOCTL_IO(LINUX_TCFLSH
, linux_ioctl_TCFLSH
),
1188 MAPPED_IOCTL_MAP(LINUX_TIOCEXCL
, TIOCEXCL
),
1189 MAPPED_IOCTL_MAP(LINUX_TIOCNXCL
, TIOCNXCL
),
1190 MAPPED_IOCTL_MAP(LINUX_TIOCGPGRP
, TIOCGPGRP
),
1191 MAPPED_IOCTL_MAP(LINUX_TIOCSPGRP
, TIOCSPGRP
),
1192 MAPPED_IOCTL_MAP(LINUX_TIOCGWINSZ
, TIOCGWINSZ
),
1193 MAPPED_IOCTL_MAP(LINUX_TIOCSWINSZ
, TIOCSWINSZ
),
1194 MAPPED_IOCTL_MAP(LINUX_TIOCMGET
, TIOCMGET
),
1195 MAPPED_IOCTL_MAP(LINUX_TIOCMBIS
, TIOCMBIS
),
1196 MAPPED_IOCTL_MAP(LINUX_TIOCMBIC
, TIOCMBIC
),
1197 MAPPED_IOCTL_MAP(LINUX_TIOCMSET
, TIOCMSET
),
1198 MAPPED_IOCTL_MAP(LINUX_FIONREAD
, FIONREAD
),
1199 MAPPED_IOCTL_MAP(LINUX_TIOCCONS
, TIOCCONS
),
1200 MAPPED_IOCTL_IOR(LINUX_TIOCGSERIAL
, linux_ioctl_TIOCGSERIAL
, struct linux_serial_struct
),
1201 MAPPED_IOCTL_IOW(LINUX_TIOCSSERIAL
, linux_ioctl_TIOCSSERIAL
, struct linux_serial_struct
),
1202 MAPPED_IOCTL_MAP(LINUX_FIONBIO
, FIONBIO
),
1203 MAPPED_IOCTL_MAP(LINUX_TIOCNOTTY
, TIOCNOTTY
),
1204 MAPPED_IOCTL_IO(LINUX_TIOCSETD
, linux_ioctl_TIOCSETD
),
1205 MAPPED_IOCTL_IOR(LINUX_TIOCGETD
, linux_ioctl_TIOCGETD
, int),
1206 MAPPED_IOCTL_MAP(LINUX_FIONCLEX
, FIONCLEX
),
1207 MAPPED_IOCTL_MAP(LINUX_FIOCLEX
, FIOCLEX
),
1208 MAPPED_IOCTL_MAP(LINUX_FIOASYNC
, FIOASYNC
),
1210 MAPPED_IOCTL_MAP(LINUX_CDROMPAUSE
, CDIOCPAUSE
),
1211 MAPPED_IOCTL_MAP(LINUX_CDROMRESUME
, CDIOCRESUME
),
1212 MAPPED_IOCTL_MAP(LINUX_CDROMPLAYMSF
, CDIOCPLAYMSF
),
1213 MAPPED_IOCTL_MAP(LINUX_CDROMPLAYTRKIND
, CDIOCPLAYTRACKS
),
1214 MAPPED_IOCTL_IOR(LINUX_CDROMREADTOCHDR
, linux_ioctl_CDROMREADTOCHDR
, struct linux_cdrom_tochdr
),
1215 MAPPED_IOCTL_IOWR(LINUX_CDROMREADTOCENTRY
, linux_ioctl_CDROMREADTOCENTRY
, struct linux_cdrom_tocentry
),
1216 MAPPED_IOCTL_MAP(LINUX_CDROMSTOP
, CDIOCSTOP
),
1217 MAPPED_IOCTL_MAP(LINUX_CDROMSTART
, CDIOCSTART
),
1218 MAPPED_IOCTL_MAP(LINUX_CDROMEJECT
, CDIOCEJECT
),
1219 MAPPED_IOCTL_IOWR(LINUX_CDROMSUBCHNL
, linux_ioctl_CDROMSUBCHNL
, struct linux_cdrom_subchnl
),
1220 MAPPED_IOCTL_MAP(LINUX_CDROMRESET
, CDIOCRESET
),
1222 MAPPED_IOCTL_MAPRANGE(LINUX_SOUND_MIXER_WRITE_MIN
, LINUX_SOUND_MIXER_WRITE_MAX
,
1223 LINUX_SOUND_MIXER_WRITE_MIN
, LINUX_SOUND_MIXER_WRITE_MAX
,
1224 NULL
, linux_gen_dirmap
),
1225 MAPPED_IOCTL_IOR(LINUX_OSS_GETVERSION
, linux_ioctl_OSS_GETVERSION
, int),
1226 MAPPED_IOCTL_MAP(LINUX_SOUND_MIXER_READ_DEVMASK
, SOUND_MIXER_READ_DEVMASK
),
1227 MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_DSP_MIN
, LINUX_SNDCTL_DSP_MAX
, LINUX_SNDCTL_DSP_MIN
,
1228 LINUX_SNDCTL_DSP_MAX
, NULL
, linux_gen_dirmap
),
1229 MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_SEQ_MIN
, LINUX_SNDCTL_SEQ_MAX
, LINUX_SNDCTL_SEQ_MIN
,
1230 LINUX_SNDCTL_SEQ_MAX
, NULL
, linux_gen_dirmap
),
1232 MAPPED_IOCTL_MAP(LINUX_KIOCSOUND
, KIOCSOUND
),
1233 MAPPED_IOCTL_MAP(LINUX_KDMKTONE
, KDMKTONE
),
1234 MAPPED_IOCTL_MAP(LINUX_KDGETLED
, KDGETLED
),
1235 MAPPED_IOCTL_MAP(LINUX_KDSETLED
, KDSETLED
),
1236 MAPPED_IOCTL_MAP(LINUX_KDSETMODE
, KDSETMODE
),
1237 MAPPED_IOCTL_MAP(LINUX_KDGETMODE
, KDGETMODE
),
1238 MAPPED_IOCTL_MAP(LINUX_KDGKBMODE
, KDGKBMODE
),
1239 MAPPED_IOCTL_IOW(LINUX_KDSKBMODE
, linux_ioctl_KDSKBMODE
, int),
1240 MAPPED_IOCTL_MAP(LINUX_VT_OPENQRY
, VT_OPENQRY
),
1241 MAPPED_IOCTL_MAP(LINUX_VT_GETMODE
, VT_GETMODE
),
1242 MAPPED_IOCTL_IOW(LINUX_VT_SETMODE
, linux_ioctl_VT_SETMODE
, struct vt_mode
),
1243 MAPPED_IOCTL_MAP(LINUX_VT_GETSTATE
, VT_GETACTIVE
),
1244 MAPPED_IOCTL_MAP(LINUX_VT_RELDISP
, VT_RELDISP
),
1245 MAPPED_IOCTL_MAP(LINUX_VT_ACTIVATE
, VT_ACTIVATE
),
1246 MAPPED_IOCTL_MAP(LINUX_VT_WAITACTIVE
, VT_WAITACTIVE
),
1248 MAPPED_IOCTL_MAP(LINUX_FIOSETOWN
, FIOSETOWN
),
1249 MAPPED_IOCTL_MAP(LINUX_SIOCSPGRP
, SIOCSPGRP
),
1250 MAPPED_IOCTL_MAP(LINUX_FIOGETOWN
, FIOGETOWN
),
1251 MAPPED_IOCTL_MAP(LINUX_SIOCGPGRP
, SIOCGPGRP
),
1252 MAPPED_IOCTL_MAP(LINUX_SIOCATMARK
, SIOCATMARK
),
1253 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFCONF
, linux_ioctl_SIOCGIFCONF
, struct ifconf
),
1254 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFFLAGS
, linux_ioctl_SIOCGIFFLAGS
, struct l_ifreq
),
1255 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFADDR
, OSIOCGIFADDR
, linux_ioctl_map_ifname
),
1256 MAPPED_IOCTL_MAPF(LINUX_SIOCSIFADDR
, SIOCSIFADDR
, linux_ioctl_map_ifname
),
1257 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFDSTADDR
, OSIOCGIFDSTADDR
, linux_ioctl_map_ifname
),
1258 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFBRDADDR
, OSIOCGIFBRDADDR
, linux_ioctl_map_ifname
),
1259 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFNETMASK
, OSIOCGIFNETMASK
, linux_ioctl_map_ifname
),
1260 /*MAPPED_IOCTL_IOx(LINUX_SIOCSIFNETMASK, x, x),*/
1261 MAPPED_IOCTL_MAPF(LINUX_SIOCGIFMTU
, SIOCGIFMTU
, linux_ioctl_map_ifname
),
1262 MAPPED_IOCTL_MAPF(LINUX_SIOCSIFMTU
, SIOCSIFMTU
, linux_ioctl_map_ifname
),
1263 MAPPED_IOCTL_IOWR(LINUX_SIOCGIFHWADDR
, linux_ioctl_SIOGIFHWADDR
, struct l_ifreq
),
1264 MAPPED_IOCTL_MAP(LINUX_SIOCADDMULTI
, SIOCADDMULTI
),
1265 MAPPED_IOCTL_MAP(LINUX_SIOCDELMULTI
, SIOCDELMULTI
),
1267 * XXX This is slightly bogus, but these ioctls are currently
1268 * XXX only used by the aironet (if_an) network driver.
1270 MAPPED_IOCTL_MAPF(LINUX_SIOCDEVPRIVATE
, SIOCGPRIVATE_0
, linux_ioctl_map_ifname
),
1271 MAPPED_IOCTL_MAPF(LINUX_SIOCDEVPRIVATE
+1, SIOCGPRIVATE_1
, linux_ioctl_map_ifname
),
1272 MAPPED_IOCTL_MAPF(0, 0, NULL
)
1275 struct ioctl_map linux_ioctl_map
= {
1277 "linux", /* subsys */
1278 LIST_HEAD_INITIALIZER(mapping
)
1281 static struct ioctl_map_handler linux_ioctl_base_handler
= {
1284 linux_ioctl_map_entries
1288 * main ioctl syscall function
1292 sys_linux_ioctl(struct linux_ioctl_args
*args
)
1296 kprintf(ARGS(ioctl
, "%d, %04x, *"), args
->fd
, args
->cmd
);
1299 return (mapped_ioctl(args
->fd
, args
->cmd
, (caddr_t
)args
->arg
, &linux_ioctl_map
));
1302 SYSINIT (linux_ioctl_register
, SI_BOOT2_KLD
, SI_ORDER_MIDDLE
,
1303 mapped_ioctl_register_handler
, &linux_ioctl_base_handler
);
1304 SYSUNINIT(linux_ioctl_register
, SI_BOOT2_KLD
, SI_ORDER_MIDDLE
,
1305 mapped_ioctl_unregister_handler
, &linux_ioctl_base_handler
);