xref: /freebsd/sys/compat/linux/linux_ioctl.c (revision 3be5f1f5ce6c92fb28926e7d02f855c12d534c34)
1 /*
2  * Copyright (c) 1994-1995 S�ren Schmidt
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software withough specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *  $Id: linux_ioctl.c,v 1.34 1999/07/06 11:41:48 marcel Exp $
29  */
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/sysproto.h>
34 #include <sys/proc.h>
35 #include <sys/cdio.h>
36 #include <sys/fcntl.h>
37 #include <sys/file.h>
38 #include <sys/filedesc.h>
39 #include <sys/filio.h>
40 #include <sys/tty.h>
41 #include <sys/socket.h>
42 #include <net/if.h>
43 #include <net/if_dl.h>
44 #include <net/if_types.h>
45 #include <sys/sockio.h>
46 
47 #include <machine/soundcard.h>
48 #include <machine/console.h>
49 
50 #include <i386/linux/linux.h>
51 #include <i386/linux/linux_proto.h>
52 
53 #define ISSIGVALID(sig)		((sig) > 0 && (sig) < NSIG)
54 
55 struct linux_termio {
56     unsigned short c_iflag;
57     unsigned short c_oflag;
58     unsigned short c_cflag;
59     unsigned short c_lflag;
60     unsigned char c_line;
61     unsigned char c_cc[LINUX_NCC];
62 };
63 
64 
65 struct linux_termios {
66     unsigned long   c_iflag;
67     unsigned long   c_oflag;
68     unsigned long   c_cflag;
69     unsigned long   c_lflag;
70     unsigned char   c_line;
71     unsigned char   c_cc[LINUX_NCCS];
72 };
73 
74 struct linux_winsize {
75     unsigned short ws_row, ws_col;
76     unsigned short ws_xpixel, ws_ypixel;
77 };
78 
79 static struct speedtab sptab[] = {
80     { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
81     { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
82     { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
83     { 2400, 11 }, { 4800, 12 }, { 9600, 13 },
84     { 19200, 14 }, { 38400, 15 },
85     { 57600, 4097 }, { 115200, 4098 }, {-1, -1 }
86 };
87 
88 struct linux_serial_struct {
89         int     type;
90         int     line;
91         int     port;
92         int     irq;
93         int     flags;
94         int     xmit_fifo_size;
95         int     custom_divisor;
96         int     baud_base;
97         unsigned short  close_delay;
98         char    reserved_char[2];
99         int     hub6;
100         unsigned short  closing_wait;
101         unsigned short  closing_wait2;
102         int     reserved[4];
103 };
104 
105 
106 static int
107 linux_to_bsd_speed(int code, struct speedtab *table)
108 {
109     for ( ; table->sp_code != -1; table++)
110 	if (table->sp_code == code)
111 	    return (table->sp_speed);
112     return -1;
113 }
114 
115 static int
116 bsd_to_linux_speed(int speed, struct speedtab *table)
117 {
118     for ( ; table->sp_speed != -1; table++)
119 	if (table->sp_speed == speed)
120 	    return (table->sp_code);
121     return -1;
122 }
123 
124 static void
125 bsd_to_linux_termios(struct termios *bsd_termios,
126 		struct linux_termios *linux_termios)
127 {
128     int i;
129 
130 #ifdef DEBUG
131     printf("LINUX: BSD termios structure (input):\n");
132     printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
133 	   bsd_termios->c_iflag, bsd_termios->c_oflag,
134 	   bsd_termios->c_cflag, bsd_termios->c_lflag,
135 	   bsd_termios->c_ispeed, bsd_termios->c_ospeed);
136     printf("c_cc ");
137     for (i=0; i<NCCS; i++)
138 	printf("%02x ", bsd_termios->c_cc[i]);
139     printf("\n");
140 #endif
141     linux_termios->c_iflag = 0;
142     if (bsd_termios->c_iflag & IGNBRK)
143 	linux_termios->c_iflag |= LINUX_IGNBRK;
144     if (bsd_termios->c_iflag & BRKINT)
145 	linux_termios->c_iflag |= LINUX_BRKINT;
146     if (bsd_termios->c_iflag & IGNPAR)
147 	linux_termios->c_iflag |= LINUX_IGNPAR;
148     if (bsd_termios->c_iflag & PARMRK)
149 	linux_termios->c_iflag |= LINUX_PARMRK;
150     if (bsd_termios->c_iflag & INPCK)
151 	linux_termios->c_iflag |= LINUX_INPCK;
152     if (bsd_termios->c_iflag & ISTRIP)
153 	linux_termios->c_iflag |= LINUX_ISTRIP;
154     if (bsd_termios->c_iflag & INLCR)
155 	linux_termios->c_iflag |= LINUX_INLCR;
156     if (bsd_termios->c_iflag & IGNCR)
157 	linux_termios->c_iflag |= LINUX_IGNCR;
158     if (bsd_termios->c_iflag & ICRNL)
159 	linux_termios->c_iflag |= LINUX_ICRNL;
160     if (bsd_termios->c_iflag & IXON)
161 	linux_termios->c_iflag |= LINUX_IXANY;
162     if (bsd_termios->c_iflag & IXON)
163 	linux_termios->c_iflag |= LINUX_IXON;
164     if (bsd_termios->c_iflag & IXOFF)
165 	linux_termios->c_iflag |= LINUX_IXOFF;
166     if (bsd_termios->c_iflag & IMAXBEL)
167 	linux_termios->c_iflag |= LINUX_IMAXBEL;
168 
169     linux_termios->c_oflag = 0;
170     if (bsd_termios->c_oflag & OPOST)
171 	linux_termios->c_oflag |= LINUX_OPOST;
172     if (bsd_termios->c_oflag & ONLCR)
173 	linux_termios->c_oflag |= LINUX_ONLCR;
174     if (bsd_termios->c_oflag & OXTABS)
175 	linux_termios->c_oflag |= LINUX_XTABS;
176 
177     linux_termios->c_cflag =
178 	bsd_to_linux_speed(bsd_termios->c_ispeed, sptab);
179     linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4;
180     if (bsd_termios->c_cflag & CSTOPB)
181 	linux_termios->c_cflag |= LINUX_CSTOPB;
182     if (bsd_termios->c_cflag & CREAD)
183 	linux_termios->c_cflag |= LINUX_CREAD;
184     if (bsd_termios->c_cflag & PARENB)
185 	linux_termios->c_cflag |= LINUX_PARENB;
186     if (bsd_termios->c_cflag & PARODD)
187 	linux_termios->c_cflag |= LINUX_PARODD;
188     if (bsd_termios->c_cflag & HUPCL)
189 	linux_termios->c_cflag |= LINUX_HUPCL;
190     if (bsd_termios->c_cflag & CLOCAL)
191 	linux_termios->c_cflag |= LINUX_CLOCAL;
192     if (bsd_termios->c_cflag & CRTSCTS)
193 	linux_termios->c_cflag |= LINUX_CRTSCTS;
194 
195     linux_termios->c_lflag = 0;
196     if (bsd_termios->c_lflag & ISIG)
197 	linux_termios->c_lflag |= LINUX_ISIG;
198     if (bsd_termios->c_lflag & ICANON)
199 	linux_termios->c_lflag |= LINUX_ICANON;
200     if (bsd_termios->c_lflag & ECHO)
201 	linux_termios->c_lflag |= LINUX_ECHO;
202     if (bsd_termios->c_lflag & ECHOE)
203 	linux_termios->c_lflag |= LINUX_ECHOE;
204     if (bsd_termios->c_lflag & ECHOK)
205 	linux_termios->c_lflag |= LINUX_ECHOK;
206     if (bsd_termios->c_lflag & ECHONL)
207 	linux_termios->c_lflag |= LINUX_ECHONL;
208     if (bsd_termios->c_lflag & NOFLSH)
209 	linux_termios->c_lflag |= LINUX_NOFLSH;
210     if (bsd_termios->c_lflag & TOSTOP)
211 	linux_termios->c_lflag |= LINUX_TOSTOP;
212     if (bsd_termios->c_lflag & ECHOCTL)
213 	linux_termios->c_lflag |= LINUX_ECHOCTL;
214     if (bsd_termios->c_lflag & ECHOPRT)
215 	linux_termios->c_lflag |= LINUX_ECHOPRT;
216     if (bsd_termios->c_lflag & ECHOKE)
217 	linux_termios->c_lflag |= LINUX_ECHOKE;
218     if (bsd_termios->c_lflag & FLUSHO)
219 	linux_termios->c_lflag |= LINUX_FLUSHO;
220     if (bsd_termios->c_lflag & PENDIN)
221 	linux_termios->c_lflag |= LINUX_PENDIN;
222     if (bsd_termios->c_lflag & IEXTEN)
223 	linux_termios->c_lflag |= LINUX_IEXTEN;
224 
225     for (i=0; i<LINUX_NCCS; i++)
226 	linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
227     linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR];
228     linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT];
229     linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE];
230     linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL];
231     linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF];
232     linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL];
233     linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN];
234     linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME];
235     linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2];
236     linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE;
237     linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP];
238     linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART];
239     linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP];
240     linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT];
241     linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD];
242     linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE];
243     linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT];
244 
245     for (i=0; i<LINUX_NCCS; i++) {
246       if (linux_termios->c_cc[i] == _POSIX_VDISABLE)
247 	linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
248     }
249 
250     linux_termios->c_line = 0;
251 #ifdef DEBUG
252     printf("LINUX: LINUX termios structure (output):\n");
253     printf("i=%08lx o=%08lx c=%08lx l=%08lx line=%d\n",
254 	linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
255 	linux_termios->c_lflag, linux_termios->c_line);
256     printf("c_cc ");
257     for (i=0; i<LINUX_NCCS; i++)
258 	printf("%02x ", linux_termios->c_cc[i]);
259     printf("\n");
260 #endif
261 }
262 
263 
264 static void
265 linux_to_bsd_termios(struct linux_termios *linux_termios,
266 		struct termios *bsd_termios)
267 {
268     int i;
269 #ifdef DEBUG
270     printf("LINUX: LINUX termios structure (input):\n");
271     printf("i=%08lx o=%08lx c=%08lx l=%08lx line=%d\n",
272 	linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
273 	linux_termios->c_lflag, linux_termios->c_line);
274     printf("c_cc ");
275     for (i=0; i<LINUX_NCCS; i++)
276 	printf("%02x ", linux_termios->c_cc[i]);
277     printf("\n");
278 #endif
279     bsd_termios->c_iflag = 0;
280     if (linux_termios->c_iflag & LINUX_IGNBRK)
281 	bsd_termios->c_iflag |= IGNBRK;
282     if (linux_termios->c_iflag & LINUX_BRKINT)
283 	bsd_termios->c_iflag |= BRKINT;
284     if (linux_termios->c_iflag & LINUX_IGNPAR)
285 	bsd_termios->c_iflag |= IGNPAR;
286     if (linux_termios->c_iflag & LINUX_PARMRK)
287 	bsd_termios->c_iflag |= PARMRK;
288     if (linux_termios->c_iflag & LINUX_INPCK)
289 	bsd_termios->c_iflag |= INPCK;
290     if (linux_termios->c_iflag & LINUX_ISTRIP)
291 	bsd_termios->c_iflag |= ISTRIP;
292     if (linux_termios->c_iflag & LINUX_INLCR)
293 	bsd_termios->c_iflag |= INLCR;
294     if (linux_termios->c_iflag & LINUX_IGNCR)
295 	bsd_termios->c_iflag |= IGNCR;
296     if (linux_termios->c_iflag & LINUX_ICRNL)
297 	bsd_termios->c_iflag |= ICRNL;
298     if (linux_termios->c_iflag & LINUX_IXON)
299 	bsd_termios->c_iflag |= IXANY;
300     if (linux_termios->c_iflag & LINUX_IXON)
301 	bsd_termios->c_iflag |= IXON;
302     if (linux_termios->c_iflag & LINUX_IXOFF)
303 	bsd_termios->c_iflag |= IXOFF;
304     if (linux_termios->c_iflag & LINUX_IMAXBEL)
305 	bsd_termios->c_iflag |= IMAXBEL;
306 
307     bsd_termios->c_oflag = 0;
308     if (linux_termios->c_oflag & LINUX_OPOST)
309 	bsd_termios->c_oflag |= OPOST;
310     if (linux_termios->c_oflag & LINUX_ONLCR)
311 	bsd_termios->c_oflag |= ONLCR;
312     if (linux_termios->c_oflag & LINUX_XTABS)
313 	bsd_termios->c_oflag |= OXTABS;
314 
315     bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4;
316     if (linux_termios->c_cflag & LINUX_CSTOPB)
317 	bsd_termios->c_cflag |= CSTOPB;
318     if (linux_termios->c_cflag & LINUX_PARENB)
319 	bsd_termios->c_cflag |= PARENB;
320     if (linux_termios->c_cflag & LINUX_PARODD)
321 	bsd_termios->c_cflag |= PARODD;
322     if (linux_termios->c_cflag & LINUX_HUPCL)
323 	bsd_termios->c_cflag |= HUPCL;
324     if (linux_termios->c_cflag & LINUX_CLOCAL)
325 	bsd_termios->c_cflag |= CLOCAL;
326     if (linux_termios->c_cflag & LINUX_CRTSCTS)
327 	bsd_termios->c_cflag |= CRTSCTS;
328 
329     bsd_termios->c_lflag = 0;
330     if (linux_termios->c_lflag & LINUX_ISIG)
331 	bsd_termios->c_lflag |= ISIG;
332     if (linux_termios->c_lflag & LINUX_ICANON)
333 	bsd_termios->c_lflag |= ICANON;
334     if (linux_termios->c_lflag & LINUX_ECHO)
335 	bsd_termios->c_lflag |= ECHO;
336     if (linux_termios->c_lflag & LINUX_ECHOE)
337 	bsd_termios->c_lflag |= ECHOE;
338     if (linux_termios->c_lflag & LINUX_ECHOK)
339 	bsd_termios->c_lflag |= ECHOK;
340     if (linux_termios->c_lflag & LINUX_ECHONL)
341 	bsd_termios->c_lflag |= ECHONL;
342     if (linux_termios->c_lflag & LINUX_NOFLSH)
343 	bsd_termios->c_lflag |= NOFLSH;
344     if (linux_termios->c_lflag & LINUX_TOSTOP)
345 	bsd_termios->c_lflag |= TOSTOP;
346     if (linux_termios->c_lflag & LINUX_ECHOCTL)
347 	bsd_termios->c_lflag |= ECHOCTL;
348     if (linux_termios->c_lflag & LINUX_ECHOPRT)
349 	bsd_termios->c_lflag |= ECHOPRT;
350     if (linux_termios->c_lflag & LINUX_ECHOKE)
351 	bsd_termios->c_lflag |= ECHOKE;
352     if (linux_termios->c_lflag & LINUX_FLUSHO)
353 	bsd_termios->c_lflag |= FLUSHO;
354     if (linux_termios->c_lflag & LINUX_PENDIN)
355 	bsd_termios->c_lflag |= PENDIN;
356     if (linux_termios->c_lflag & IEXTEN)
357 	bsd_termios->c_lflag |= IEXTEN;
358 
359     for (i=0; i<NCCS; i++)
360 	bsd_termios->c_cc[i] = _POSIX_VDISABLE;
361     bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR];
362     bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT];
363     bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE];
364     bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL];
365     bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF];
366     bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL];
367     bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN];
368     bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME];
369     bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2];
370     bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP];
371     bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART];
372     bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP];
373     bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT];
374     bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD];
375     bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE];
376     bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT];
377 
378     for (i=0; i<NCCS; i++) {
379       if (bsd_termios->c_cc[i] == LINUX_POSIX_VDISABLE)
380 	bsd_termios->c_cc[i] = _POSIX_VDISABLE;
381     }
382 
383     bsd_termios->c_ispeed = bsd_termios->c_ospeed =
384 	linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab);
385 #ifdef DEBUG
386 	printf("LINUX: BSD termios structure (output):\n");
387 	printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
388 	       bsd_termios->c_iflag, bsd_termios->c_oflag,
389 	       bsd_termios->c_cflag, bsd_termios->c_lflag,
390 	       bsd_termios->c_ispeed, bsd_termios->c_ospeed);
391 	printf("c_cc ");
392 	for (i=0; i<NCCS; i++)
393 	    printf("%02x ", bsd_termios->c_cc[i]);
394 	printf("\n");
395 #endif
396 }
397 
398 
399 static void
400 bsd_to_linux_termio(struct termios *bsd_termios,
401 		struct linux_termio *linux_termio)
402 {
403   struct linux_termios tmios;
404 
405   bsd_to_linux_termios(bsd_termios, &tmios);
406   linux_termio->c_iflag = tmios.c_iflag;
407   linux_termio->c_oflag = tmios.c_oflag;
408   linux_termio->c_cflag = tmios.c_cflag;
409   linux_termio->c_lflag = tmios.c_lflag;
410   linux_termio->c_line  = tmios.c_line;
411   memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC);
412 }
413 
414 static void
415 linux_to_bsd_termio(struct linux_termio *linux_termio,
416 		struct termios *bsd_termios)
417 {
418   struct linux_termios tmios;
419   int i;
420 
421   tmios.c_iflag = linux_termio->c_iflag;
422   tmios.c_oflag = linux_termio->c_oflag;
423   tmios.c_cflag = linux_termio->c_cflag;
424   tmios.c_lflag = linux_termio->c_lflag;
425 
426   for (i=0; i<LINUX_NCCS; i++)
427     tmios.c_cc[i] = LINUX_POSIX_VDISABLE;
428   memcpy(tmios.c_cc, linux_termio->c_cc, LINUX_NCC);
429 
430   linux_to_bsd_termios(&tmios, bsd_termios);
431 }
432 
433 static void
434 linux_tiocgserial(struct file *fp, struct linux_serial_struct *lss)
435 {
436   if (!fp || !lss)
437     return;
438 
439   lss->type = LINUX_PORT_16550A;
440   lss->flags = 0;
441   lss->close_delay = 0;
442 }
443 
444 static void
445 linux_tiocsserial(struct file *fp, struct linux_serial_struct *lss)
446 {
447   if (!fp || !lss)
448     return;
449 }
450 
451 struct linux_cdrom_msf
452 {
453     u_char	cdmsf_min0;
454     u_char	cdmsf_sec0;
455     u_char	cdmsf_frame0;
456     u_char	cdmsf_min1;
457     u_char	cdmsf_sec1;
458     u_char	cdmsf_frame1;
459 };
460 
461 struct linux_cdrom_tochdr
462 {
463     u_char	cdth_trk0;
464     u_char	cdth_trk1;
465 };
466 
467 union linux_cdrom_addr
468 {
469     struct {
470 	u_char	minute;
471 	u_char	second;
472 	u_char	frame;
473     } msf;
474     int		lba;
475 };
476 
477 struct linux_cdrom_tocentry
478 {
479     u_char	cdte_track;
480     u_char	cdte_adr:4;
481     u_char	cdte_ctrl:4;
482     u_char	cdte_format;
483     union linux_cdrom_addr cdte_addr;
484     u_char	cdte_datamode;
485 };
486 
487 #if 0
488 static void
489 linux_to_bsd_msf_lba(u_char address_format,
490     union linux_cdrom_addr *lp, union msf_lba *bp)
491 {
492     if (address_format == CD_LBA_FORMAT)
493 	bp->lba = lp->lba;
494     else {
495 	bp->msf.minute = lp->msf.minute;
496 	bp->msf.second = lp->msf.second;
497 	bp->msf.frame = lp->msf.frame;
498     }
499 }
500 #endif
501 
502 static void
503 bsd_to_linux_msf_lba(u_char address_format,
504     union msf_lba *bp, union linux_cdrom_addr *lp)
505 {
506     if (address_format == CD_LBA_FORMAT)
507 	lp->lba = bp->lba;
508     else {
509 	lp->msf.minute = bp->msf.minute;
510 	lp->msf.second = bp->msf.second;
511 	lp->msf.frame = bp->msf.frame;
512     }
513 }
514 
515 static unsigned dirbits[4] = { IOC_VOID, IOC_OUT, IOC_IN, IOC_INOUT };
516 
517 #define SETDIR(c)	(((c) & ~IOC_DIRMASK) | dirbits[args->cmd >> 30])
518 
519 int
520 linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
521 {
522     struct termios bsd_termios;
523     struct linux_termios linux_termios;
524     struct linux_termio linux_termio;
525     struct filedesc *fdp = p->p_fd;
526     struct file *fp;
527     int (*func)(struct file *fp, u_long com, caddr_t data, struct proc *p);
528     int bsd_line, linux_line;
529     int error;
530 
531 #ifdef DEBUG
532     printf("Linux-emul(%ld): ioctl(%d, %04lx, *)\n",
533 	(long)p->p_pid, args->fd, args->cmd);
534 #endif
535     if ((unsigned)args->fd >= fdp->fd_nfiles
536 	|| (fp = fdp->fd_ofiles[args->fd]) == 0)
537 	return EBADF;
538 
539     if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
540 	return EBADF;
541     }
542 
543     func = fp->f_ops->fo_ioctl;
544     switch (args->cmd & 0xffff) {
545 
546     case LINUX_TCGETA:
547 	if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
548 	    return error;
549 	bsd_to_linux_termio(&bsd_termios, &linux_termio);
550 	return copyout((caddr_t)&linux_termio, (caddr_t)args->arg,
551 		       sizeof(linux_termio));
552 
553     case LINUX_TCSETA:
554 	linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios);
555 	return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
556 
557     case LINUX_TCSETAW:
558 	linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios);
559 	return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
560 
561     case LINUX_TCSETAF:
562 	linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios);
563 	return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
564 
565     case LINUX_TCGETS:
566 	if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
567 	    return error;
568 	bsd_to_linux_termios(&bsd_termios, &linux_termios);
569 	return copyout((caddr_t)&linux_termios, (caddr_t)args->arg,
570 		       sizeof(linux_termios));
571 
572     case LINUX_TCSETS:
573 	linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
574 	return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
575 
576     case LINUX_TCSETSW:
577 	linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
578 	return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
579 
580     case LINUX_TCSETSF:
581 	linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
582 	return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
583 
584     case LINUX_TIOCGPGRP:
585 	args->cmd = TIOCGPGRP;
586 	return ioctl(p, (struct ioctl_args *)args);
587 
588     case LINUX_TIOCSPGRP:
589 	args->cmd = TIOCSPGRP;
590 	return ioctl(p, (struct ioctl_args *)args);
591 
592     case LINUX_TIOCGWINSZ:
593 	args->cmd = TIOCGWINSZ;
594 	return ioctl(p, (struct ioctl_args *)args);
595 
596     case LINUX_TIOCSWINSZ:
597 	args->cmd = TIOCSWINSZ;
598 	return ioctl(p, (struct ioctl_args *)args);
599 
600     case LINUX_TIOCMGET:
601 	args->cmd = TIOCMGET;
602 	return ioctl(p, (struct ioctl_args *)args);
603 
604     case LINUX_TIOCMBIS:
605 	args->cmd = TIOCMBIS;
606 	return ioctl(p, (struct ioctl_args *)args);
607 
608     case LINUX_TIOCMBIC:
609 	args->cmd = TIOCMBIC;
610 	return ioctl(p, (struct ioctl_args *)args);
611 
612     case LINUX_TIOCMSET:
613 	args->cmd = TIOCMSET;
614 	return ioctl(p, (struct ioctl_args *)args);
615 
616     case LINUX_FIONREAD:
617 	args->cmd = FIONREAD;
618 	return ioctl(p, (struct ioctl_args *)args);
619 
620     case LINUX_FIONBIO:
621 	args->cmd = FIONBIO;
622 	return ioctl(p, (struct ioctl_args *)args);
623 
624     case LINUX_FIOASYNC:
625 	args->cmd = FIOASYNC;
626 	return ioctl(p, (struct ioctl_args *)args);
627 
628     case LINUX_FIONCLEX:
629 	args->cmd = FIONCLEX;
630 	return ioctl(p, (struct ioctl_args *)args);
631 
632     case LINUX_FIOCLEX:
633 	args->cmd = FIOCLEX;
634 	return ioctl(p, (struct ioctl_args *)args);
635 
636     case LINUX_TIOCEXCL:
637 	args->cmd = TIOCEXCL;
638 	return ioctl(p, (struct ioctl_args *)args);
639 
640     case LINUX_TIOCNXCL:
641 	args->cmd = TIOCNXCL;
642 	return ioctl(p, (struct ioctl_args *)args);
643 
644     case LINUX_TIOCCONS:
645 	args->cmd = TIOCCONS;
646 	return ioctl(p, (struct ioctl_args *)args);
647 
648     case LINUX_TIOCNOTTY:
649 	args->cmd = TIOCNOTTY;
650 	return ioctl(p, (struct ioctl_args *)args);
651 
652     case LINUX_SIOCGIFCONF:
653 	args->cmd = OSIOCGIFCONF;
654 	return ioctl(p, (struct ioctl_args *)args);
655 
656     case LINUX_SIOCGIFFLAGS:
657 	args->cmd = SIOCGIFFLAGS;
658 	return ioctl(p, (struct ioctl_args *)args);
659 
660     case LINUX_SIOCGIFADDR:
661 	args->cmd = OSIOCGIFADDR;
662 	return ioctl(p, (struct ioctl_args *)args);
663 
664     case LINUX_SIOCGIFDSTADDR:
665 	args->cmd = OSIOCGIFDSTADDR;
666 	return ioctl(p, (struct ioctl_args *)args);
667 
668     case LINUX_SIOCGIFBRDADDR:
669 	args->cmd = OSIOCGIFBRDADDR;
670 	return ioctl(p, (struct ioctl_args *)args);
671 
672     case LINUX_SIOCGIFNETMASK:
673 	args->cmd = OSIOCGIFNETMASK;
674 	return ioctl(p, (struct ioctl_args *)args);
675 
676 	/* get hardware address */
677     case LINUX_SIOCGIFHWADDR:
678     {
679 	int			ifn;
680 	struct ifnet		*ifp;
681 	struct ifaddr		*ifa;
682 	struct sockaddr_dl	*sdl;
683 	struct linux_ifreq	*ifr = (struct linux_ifreq *)args->arg;
684 
685 	/*
686 	 * Note that we don't actually respect the name in the ifreq structure, as
687 	 * Linux interface names are all different
688 	 */
689 
690 	for (ifn = 0; ifn < if_index; ifn++) {
691 
692 	    ifp = ifnet_addrs[ifn]->ifa_ifp;	/* pointer to interface */
693 	    if (ifp->if_type == IFT_ETHER) {	/* looks good */
694 		/* walk the address list */
695 		for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = TAILQ_NEXT(ifa, ifa_link)) {
696 		    if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&	/* we have an address structure */
697 			(sdl->sdl_family == AF_LINK) &&			/* it's a link address */
698 			(sdl->sdl_type == IFT_ETHER)) {			/* for an ethernet link */
699 
700 			return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_IFHWADDRLEN));
701 		    }
702 		}
703 	    }
704 	}
705 	return(ENOENT);		/* ??? */
706     }
707 
708     case LINUX_SIOCADDMULTI:
709 	args->cmd = SIOCADDMULTI;
710 	return ioctl(p, (struct ioctl_args *)args);
711 
712     case LINUX_SIOCDELMULTI:
713 	args->cmd = SIOCDELMULTI;
714 	return ioctl(p, (struct ioctl_args *)args);
715 
716     case LINUX_FIOSETOWN:
717 	args->cmd = FIOSETOWN;
718 	return ioctl(p, (struct ioctl_args *)args);
719 
720     case LINUX_SIOCSPGRP:
721 	args->cmd = SIOCSPGRP;
722 	return ioctl(p, (struct ioctl_args *)args);
723 
724     case LINUX_FIOGETOWN:
725 	args->cmd = FIOGETOWN;
726 	return ioctl(p, (struct ioctl_args *)args);
727 
728     case LINUX_SIOCGPGRP:
729 	args->cmd = SIOCGPGRP;
730 	return ioctl(p, (struct ioctl_args *)args);
731 
732     case LINUX_SIOCATMARK:
733 	args->cmd = SIOCATMARK;
734 	return ioctl(p, (struct ioctl_args *)args);
735 
736     case LINUX_TIOCSETD:
737 	switch (args->arg) {
738 	case LINUX_N_TTY:
739 	    bsd_line = TTYDISC;
740 	    return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
741 	case LINUX_N_SLIP:
742 	    bsd_line = SLIPDISC;
743 	    return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
744 	case LINUX_N_PPP:
745 	    bsd_line = PPPDISC;
746 	    return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
747 	default:
748 	    return EINVAL;
749 	}
750 
751     case LINUX_TIOCGETD:
752 	bsd_line = TTYDISC;
753 	error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
754 	if (error)
755 	    return error;
756 	switch (bsd_line) {
757 	case TTYDISC:
758 	    linux_line = LINUX_N_TTY;
759 	    break;
760 	case SLIPDISC:
761 	    linux_line = LINUX_N_SLIP;
762 	    break;
763 	case PPPDISC:
764 	    linux_line = LINUX_N_PPP;
765 	    break;
766 	default:
767 	    return EINVAL;
768 	}
769 	return copyout(&linux_line, (caddr_t)args->arg,
770 		       sizeof(int));
771 
772     case LINUX_SNDCTL_SEQ_RESET:
773 	args->cmd = SNDCTL_SEQ_RESET;
774 	return ioctl(p, (struct ioctl_args *)args);
775 
776     case LINUX_SNDCTL_SEQ_SYNC:
777 	args->cmd = SNDCTL_SEQ_SYNC;
778 	return ioctl(p, (struct ioctl_args *)args);
779 
780     case LINUX_SNDCTL_SYNTH_INFO:
781 	args->cmd = SNDCTL_SYNTH_INFO;
782 	return ioctl(p, (struct ioctl_args *)args);
783 
784     case LINUX_SNDCTL_SEQ_CTRLRATE:
785 	args->cmd = SNDCTL_SEQ_CTRLRATE;
786 	return ioctl(p, (struct ioctl_args *)args);
787 
788     case LINUX_SNDCTL_SEQ_GETOUTCOUNT:
789 	args->cmd = SNDCTL_SEQ_GETOUTCOUNT;
790 	return ioctl(p, (struct ioctl_args *)args);
791 
792     case LINUX_SNDCTL_SEQ_GETINCOUNT:
793 	args->cmd = SNDCTL_SEQ_GETINCOUNT;
794 	return ioctl(p, (struct ioctl_args *)args);
795 
796     case LINUX_SNDCTL_SEQ_PERCMODE:
797 	args->cmd = SNDCTL_SEQ_PERCMODE;
798 	return ioctl(p, (struct ioctl_args *)args);
799 
800     case LINUX_SNDCTL_FM_LOAD_INSTR:
801 	args->cmd = SNDCTL_FM_LOAD_INSTR;
802 	return ioctl(p, (struct ioctl_args *)args);
803 
804     case LINUX_SNDCTL_SEQ_TESTMIDI:
805 	args->cmd = SNDCTL_SEQ_TESTMIDI;
806 	return ioctl(p, (struct ioctl_args *)args);
807 
808     case LINUX_SNDCTL_SEQ_RESETSAMPLES:
809 	args->cmd = SNDCTL_SEQ_RESETSAMPLES;
810 	return ioctl(p, (struct ioctl_args *)args);
811 
812     case LINUX_SNDCTL_SEQ_NRSYNTHS:
813 	args->cmd = SNDCTL_SEQ_NRSYNTHS;
814 	return ioctl(p, (struct ioctl_args *)args);
815 
816     case LINUX_SNDCTL_SEQ_NRMIDIS:
817 	args->cmd = SNDCTL_SEQ_NRMIDIS;
818 	return ioctl(p, (struct ioctl_args *)args);
819 
820     case LINUX_SNDCTL_MIDI_INFO:
821 	args->cmd = SNDCTL_MIDI_INFO;
822 	return ioctl(p, (struct ioctl_args *)args);
823 
824     case LINUX_SNDCTL_SEQ_TRESHOLD:
825 	args->cmd = SNDCTL_SEQ_TRESHOLD;
826 	return ioctl(p, (struct ioctl_args *)args);
827 
828     case LINUX_SNDCTL_SYNTH_MEMAVL:
829 	args->cmd = SNDCTL_SYNTH_MEMAVL;
830 	return ioctl(p, (struct ioctl_args *)args);
831 
832     case LINUX_SNDCTL_DSP_GETOPTR :
833 	args->cmd = SNDCTL_DSP_GETOPTR;
834 	return ioctl(p, (struct ioctl_args *)args);
835 
836     case LINUX_SNDCTL_DSP_GETIPTR :
837 	args->cmd = SNDCTL_DSP_GETIPTR;
838 	return ioctl(p, (struct ioctl_args *)args);
839 
840     case LINUX_SNDCTL_DSP_SETTRIGGER:
841 	args->cmd = SNDCTL_DSP_SETTRIGGER;
842 	return ioctl(p, (struct ioctl_args *)args);
843 
844     case LINUX_SNDCTL_DSP_GETCAPS:
845 	args->cmd = SNDCTL_DSP_GETCAPS;
846 	return ioctl(p, (struct ioctl_args *)args);
847 
848     case LINUX_SNDCTL_DSP_RESET:
849 	args->cmd = SNDCTL_DSP_RESET;
850 	return ioctl(p, (struct ioctl_args *)args);
851 
852     case LINUX_SNDCTL_DSP_SYNC:
853 	args->cmd = SNDCTL_DSP_SYNC;
854 	return ioctl(p, (struct ioctl_args *)args);
855 
856     case LINUX_SNDCTL_DSP_SPEED:
857 	args->cmd = SNDCTL_DSP_SPEED;
858 	return ioctl(p, (struct ioctl_args *)args);
859 
860     case LINUX_SNDCTL_DSP_STEREO:
861 	args->cmd = SNDCTL_DSP_STEREO;
862 	return ioctl(p, (struct ioctl_args *)args);
863 
864     case LINUX_SNDCTL_DSP_GETBLKSIZE:
865       /* LINUX_SNDCTL_DSP_SETBLKSIZE */
866 	args->cmd = SNDCTL_DSP_GETBLKSIZE;
867 	return ioctl(p, (struct ioctl_args *)args);
868 
869     case LINUX_SNDCTL_DSP_SETFMT:
870 	args->cmd = SNDCTL_DSP_SETFMT;
871 	return ioctl(p, (struct ioctl_args *)args);
872 
873     case LINUX_SOUND_PCM_WRITE_CHANNELS:
874 	args->cmd = SOUND_PCM_WRITE_CHANNELS;
875 	return ioctl(p, (struct ioctl_args *)args);
876 
877     case LINUX_SOUND_PCM_WRITE_FILTER:
878 	args->cmd = SOUND_PCM_WRITE_FILTER;
879 	return ioctl(p, (struct ioctl_args *)args);
880 
881     case LINUX_SNDCTL_DSP_POST:
882 	args->cmd = SNDCTL_DSP_POST;
883 	return ioctl(p, (struct ioctl_args *)args);
884 
885     case LINUX_SNDCTL_DSP_SUBDIVIDE:
886 	args->cmd = SNDCTL_DSP_SUBDIVIDE;
887 	return ioctl(p, (struct ioctl_args *)args);
888 
889     case LINUX_SNDCTL_DSP_SETFRAGMENT:
890 	args->cmd = SNDCTL_DSP_SETFRAGMENT;
891 	return ioctl(p, (struct ioctl_args *)args);
892 
893     case LINUX_SNDCTL_DSP_GETFMTS:
894 	args->cmd = SNDCTL_DSP_GETFMTS;
895 	return ioctl(p, (struct ioctl_args *)args);
896 
897     case LINUX_SNDCTL_DSP_GETOSPACE:
898 	args->cmd = SNDCTL_DSP_GETOSPACE;
899 	return ioctl(p, (struct ioctl_args *)args);
900 
901     case LINUX_SNDCTL_DSP_GETISPACE:
902 	args->cmd = SNDCTL_DSP_GETISPACE;
903 	return ioctl(p, (struct ioctl_args *)args);
904 
905     case LINUX_SNDCTL_DSP_NONBLOCK:
906 	args->cmd = SNDCTL_DSP_NONBLOCK;
907 	return ioctl(p, (struct ioctl_args *)args);
908 
909     case LINUX_SOUND_MIXER_WRITE_VOLUME:
910 	args->cmd = SETDIR(SOUND_MIXER_WRITE_VOLUME);
911 	return ioctl(p, (struct ioctl_args *)args);
912 
913     case LINUX_SOUND_MIXER_WRITE_BASS:
914 	args->cmd = SETDIR(SOUND_MIXER_WRITE_BASS);
915 	return ioctl(p, (struct ioctl_args *)args);
916 
917     case LINUX_SOUND_MIXER_WRITE_TREBLE:
918 	args->cmd = SETDIR(SOUND_MIXER_WRITE_TREBLE);
919 	return ioctl(p, (struct ioctl_args *)args);
920 
921     case LINUX_SOUND_MIXER_WRITE_SYNTH:
922 	args->cmd = SETDIR(SOUND_MIXER_WRITE_SYNTH);
923 	return ioctl(p, (struct ioctl_args *)args);
924 
925     case LINUX_SOUND_MIXER_WRITE_PCM:
926 	args->cmd = SETDIR(SOUND_MIXER_WRITE_PCM);
927 	return ioctl(p, (struct ioctl_args *)args);
928 
929     case LINUX_SOUND_MIXER_WRITE_SPEAKER:
930 	args->cmd = SETDIR(SOUND_MIXER_WRITE_SPEAKER);
931 	return ioctl(p, (struct ioctl_args *)args);
932 
933     case LINUX_SOUND_MIXER_WRITE_LINE:
934 	args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE);
935 	return ioctl(p, (struct ioctl_args *)args);
936 
937     case LINUX_SOUND_MIXER_WRITE_MIC:
938 	args->cmd = SETDIR(SOUND_MIXER_WRITE_MIC);
939 	return ioctl(p, (struct ioctl_args *)args);
940 
941     case LINUX_SOUND_MIXER_WRITE_CD:
942 	args->cmd = SETDIR(SOUND_MIXER_WRITE_CD);
943 	return ioctl(p, (struct ioctl_args *)args);
944 
945     case LINUX_SOUND_MIXER_WRITE_IMIX:
946 	args->cmd = SETDIR(SOUND_MIXER_WRITE_IMIX);
947 	return ioctl(p, (struct ioctl_args *)args);
948 
949     case LINUX_SOUND_MIXER_WRITE_ALTPCM:
950 	args->cmd = SETDIR(SOUND_MIXER_WRITE_ALTPCM);
951 	return ioctl(p, (struct ioctl_args *)args);
952 
953     case LINUX_SOUND_MIXER_WRITE_RECLEV:
954 	args->cmd = SETDIR(SOUND_MIXER_WRITE_RECLEV);
955 	return ioctl(p, (struct ioctl_args *)args);
956 
957     case LINUX_SOUND_MIXER_WRITE_IGAIN:
958 	args->cmd = SETDIR(SOUND_MIXER_WRITE_IGAIN);
959 	return ioctl(p, (struct ioctl_args *)args);
960 
961     case LINUX_SOUND_MIXER_WRITE_OGAIN:
962 	args->cmd = SETDIR(SOUND_MIXER_WRITE_OGAIN);
963 	return ioctl(p, (struct ioctl_args *)args);
964 
965     case LINUX_SOUND_MIXER_WRITE_LINE1:
966 	args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE1);
967 	return ioctl(p, (struct ioctl_args *)args);
968 
969     case LINUX_SOUND_MIXER_WRITE_LINE2:
970 	args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE2);
971 	return ioctl(p, (struct ioctl_args *)args);
972 
973     case LINUX_SOUND_MIXER_WRITE_LINE3:
974 	args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE3);
975 	return ioctl(p, (struct ioctl_args *)args);
976 
977     case LINUX_SOUND_MIXER_READ_DEVMASK:
978 	args->cmd = SOUND_MIXER_READ_DEVMASK;
979 	return ioctl(p, (struct ioctl_args *)args);
980 
981     case LINUX_TIOCGSERIAL:
982         linux_tiocgserial(fp, (struct linux_serial_struct *)args->arg);
983         return 0;
984 
985     case LINUX_TIOCSSERIAL:
986         linux_tiocsserial(fp, (struct linux_serial_struct *)args->arg);
987 	return 0;
988 
989     case LINUX_TCFLSH:
990       args->cmd = TIOCFLUSH;
991       switch (args->arg) {
992         case LINUX_TCIFLUSH:
993                 args->arg = FREAD;
994                 break;
995         case LINUX_TCOFLUSH:
996                 args->arg = FWRITE;
997                 break;
998         case LINUX_TCIOFLUSH:
999                 args->arg = FREAD | FWRITE;
1000                 break;
1001         default:
1002 	        return EINVAL;
1003       }
1004       return ioctl(p, (struct ioctl_args *)args);
1005 
1006    case LINUX_VT_OPENQRY:
1007 
1008 	args->cmd = VT_OPENQRY;
1009 	return  ioctl(p, (struct ioctl_args *)args);
1010 
1011     case LINUX_VT_GETMODE:
1012 
1013 	args->cmd = VT_GETMODE;
1014 	return  ioctl(p, (struct ioctl_args *)args);
1015 
1016     case LINUX_VT_SETMODE:
1017       {
1018 	struct vt_mode *mode;
1019 	args->cmd = VT_SETMODE;
1020 	mode = (struct vt_mode *)args->arg;
1021 	if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig))
1022 	    mode->frsig = mode->acqsig;
1023 	return ioctl(p, (struct ioctl_args *)args);
1024       }
1025 
1026     case LINUX_VT_GETSTATE:
1027 
1028 	args->cmd = VT_GETACTIVE;
1029 	return  ioctl(p, (struct ioctl_args *)args);
1030 
1031     case LINUX_VT_RELDISP:
1032 
1033        args->cmd = VT_RELDISP;
1034        return  ioctl(p, (struct ioctl_args *)args);
1035 
1036     case LINUX_VT_ACTIVATE:
1037 
1038 	args->cmd = VT_ACTIVATE;
1039 	return  ioctl(p, (struct ioctl_args *)args);
1040 
1041     case LINUX_VT_WAITACTIVE:
1042 
1043 	args->cmd = VT_WAITACTIVE;
1044 	return  ioctl(p, (struct ioctl_args *)args);
1045 
1046     case LINUX_KDGKBMODE:
1047 
1048 	args->cmd = KDGKBMODE;
1049 	return ioctl(p, (struct ioctl_args *)args);
1050 
1051     case LINUX_KDSKBMODE:
1052       {
1053         int kbdmode;
1054 	switch (args->arg) {
1055 	case LINUX_KBD_RAW:
1056 	    kbdmode = K_RAW;
1057 	    return (*func)(fp, KDSKBMODE, (caddr_t)&kbdmode, p);
1058 	case LINUX_KBD_XLATE:
1059 	    kbdmode = K_XLATE;
1060 	    return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
1061 	case LINUX_KBD_MEDIUMRAW:
1062 	    kbdmode = K_RAW;
1063 	    return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
1064 	default:
1065 	    return EINVAL;
1066 	}
1067       }
1068 
1069     case LINUX_KDGETMODE:
1070 	args->cmd = KDGETMODE;
1071 	return	ioctl(p, (struct ioctl_args *)args);
1072 
1073     case LINUX_KDSETMODE:
1074 	args->cmd = KDSETMODE;
1075 	return	ioctl(p, (struct ioctl_args *)args);
1076 
1077     case LINUX_KDSETLED:
1078 	args->cmd = KDSETLED;
1079 	return  ioctl(p, (struct ioctl_args *)args);
1080 
1081     case LINUX_KDGETLED:
1082 	args->cmd = KDGETLED;
1083 	return  ioctl(p, (struct ioctl_args *)args);
1084 
1085     case LINUX_KIOCSOUND:
1086 	args->cmd = KIOCSOUND;
1087 	return  ioctl(p, (struct ioctl_args *)args);
1088 
1089     case LINUX_KDMKTONE:
1090 	args->cmd = KDMKTONE;
1091 	return  ioctl(p, (struct ioctl_args *)args);
1092 
1093 
1094     case LINUX_CDROMPAUSE:
1095 	args->cmd = CDIOCPAUSE;
1096 	return	ioctl(p, (struct ioctl_args *)args);
1097 
1098     case LINUX_CDROMRESUME:
1099 	args->cmd = CDIOCRESUME;
1100 	return	ioctl(p, (struct ioctl_args *)args);
1101 
1102     case LINUX_CDROMPLAYMSF:
1103 	args->cmd = CDIOCPLAYMSF;
1104 	return	ioctl(p, (struct ioctl_args *)args);
1105 
1106     case LINUX_CDROMPLAYTRKIND:
1107 	args->cmd = CDIOCPLAYTRACKS;
1108 	return	ioctl(p, (struct ioctl_args *)args);
1109 
1110     case LINUX_CDROMSTART:
1111 	args->cmd = CDIOCSTART;
1112 	return	ioctl(p, (struct ioctl_args *)args);
1113 
1114     case LINUX_CDROMSTOP:
1115 	args->cmd = CDIOCSTOP;
1116 	return	ioctl(p, (struct ioctl_args *)args);
1117 
1118     case LINUX_CDROMEJECT:
1119 	args->cmd = CDIOCEJECT;
1120 	return	ioctl(p, (struct ioctl_args *)args);
1121 
1122     case LINUX_CDROMRESET:
1123 	args->cmd = CDIOCRESET;
1124 	return	ioctl(p, (struct ioctl_args *)args);
1125 
1126     case LINUX_CDROMREADTOCHDR: {
1127 	struct ioc_toc_header th;
1128 	struct linux_cdrom_tochdr lth;
1129 	error = (*func)(fp, CDIOREADTOCHEADER, (caddr_t)&th, p);
1130 	if (!error) {
1131 	    lth.cdth_trk0 = th.starting_track;
1132 	    lth.cdth_trk1 = th.ending_track;
1133 	    copyout((caddr_t)&lth, (caddr_t)args->arg, sizeof(lth));
1134 	}
1135 	return error;
1136     }
1137 
1138     case LINUX_CDROMREADTOCENTRY: {
1139 	struct linux_cdrom_tocentry lte, *ltep =
1140 	    (struct linux_cdrom_tocentry *)args->arg;
1141 	struct ioc_read_toc_single_entry irtse;
1142 	irtse.address_format = ltep->cdte_format;
1143 	irtse.track = ltep->cdte_track;
1144 	error = (*func)(fp, CDIOREADTOCENTRY, (caddr_t)&irtse, p);
1145 	if (!error) {
1146 	    lte = *ltep;
1147 	    lte.cdte_ctrl = irtse.entry.control;
1148 	    lte.cdte_adr = irtse.entry.addr_type;
1149 	    bsd_to_linux_msf_lba(irtse.address_format,
1150 		&irtse.entry.addr, &lte.cdte_addr);
1151 	    copyout((caddr_t)&lte, (caddr_t)args->arg, sizeof(lte));
1152 	}
1153 	return error;
1154     }
1155 
1156     }
1157 
1158     uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
1159 	args->fd, (u_int)((args->cmd & 0xffff00) >> 8),
1160 	(int)((args->cmd & 0xffff00) >> 8), (u_int)(args->cmd & 0xff));
1161     return EINVAL;
1162 }
1163