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 * $FreeBSD: src/sys/i386/linux/linux_ioctl.c,v 1.11.2.8 1999/09/05 08:14:14 peter 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/ioctl.h>
36 #include <sys/ioctl_compat.h>
37 #include <sys/file.h>
38 #include <sys/filedesc.h>
39 #include <sys/tty.h>
40 #include <sys/termios.h>
41 #include <sys/socket.h>
42 #include <sys/ioctl.h>
43 #include <net/if.h>
44 #include <net/if_dl.h>
45 #include <net/if_types.h>
46 #include <sys/sockio.h>
47
48 #include <machine/soundcard.h>
49 #include <machine/console.h>
50
51 #include <i386/linux/linux.h>
52 #include <i386/linux/linux_proto.h>
53
54 #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
55
56 struct linux_termio {
57 unsigned short c_iflag;
58 unsigned short c_oflag;
59 unsigned short c_cflag;
60 unsigned short c_lflag;
61 unsigned char c_line;
62 unsigned char c_cc[LINUX_NCC];
63 };
64
65
66 struct linux_termios {
67 unsigned long c_iflag;
68 unsigned long c_oflag;
69 unsigned long c_cflag;
70 unsigned long c_lflag;
71 unsigned char c_line;
72 unsigned char c_cc[LINUX_NCCS];
73 };
74
75 struct linux_winsize {
76 unsigned short ws_row, ws_col;
77 unsigned short ws_xpixel, ws_ypixel;
78 };
79
80 static struct speedtab sptab[] = {
81 { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
82 { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
83 { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
84 { 2400, 11 }, { 4800, 12 }, { 9600, 13 },
85 { 19200, 14 }, { 38400, 15 },
86 { 57600, 4097 }, { 115200, 4098 }, {-1, -1 }
87 };
88
89 struct linux_serial_struct {
90 int type;
91 int line;
92 int port;
93 int irq;
94 int flags;
95 int xmit_fifo_size;
96 int custom_divisor;
97 int baud_base;
98 unsigned short close_delay;
99 char reserved_char[2];
100 int hub6;
101 unsigned short closing_wait;
102 unsigned short closing_wait2;
103 int reserved[4];
104 };
105
106
107 static int
108 linux_to_bsd_speed(int code, struct speedtab *table)
109 {
110 for ( ; table->sp_code != -1; table++)
111 if (table->sp_code == code)
112 return (table->sp_speed);
113 return -1;
114 }
115
116 static int
117 bsd_to_linux_speed(int speed, struct speedtab *table)
118 {
119 for ( ; table->sp_speed != -1; table++)
120 if (table->sp_speed == speed)
121 return (table->sp_code);
122 return -1;
123 }
124
125 static void
126 bsd_to_linux_termios(struct termios *bsd_termios,
127 struct linux_termios *linux_termios)
128 {
129 int i;
130
131 #ifdef DEBUG
132 printf("LINUX: BSD termios structure (input):\n");
133 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
134 bsd_termios->c_iflag, bsd_termios->c_oflag,
135 bsd_termios->c_cflag, bsd_termios->c_lflag,
136 bsd_termios->c_ispeed, bsd_termios->c_ospeed);
137 printf("c_cc ");
138 for (i=0; i<NCCS; i++)
139 printf("%02x ", bsd_termios->c_cc[i]);
140 printf("\n");
141 #endif
142 linux_termios->c_iflag = 0;
143 if (bsd_termios->c_iflag & IGNBRK)
144 linux_termios->c_iflag |= LINUX_IGNBRK;
145 if (bsd_termios->c_iflag & BRKINT)
146 linux_termios->c_iflag |= LINUX_BRKINT;
147 if (bsd_termios->c_iflag & IGNPAR)
148 linux_termios->c_iflag |= LINUX_IGNPAR;
149 if (bsd_termios->c_iflag & PARMRK)
150 linux_termios->c_iflag |= LINUX_PARMRK;
151 if (bsd_termios->c_iflag & INPCK)
152 linux_termios->c_iflag |= LINUX_INPCK;
153 if (bsd_termios->c_iflag & ISTRIP)
154 linux_termios->c_iflag |= LINUX_ISTRIP;
155 if (bsd_termios->c_iflag & INLCR)
156 linux_termios->c_iflag |= LINUX_INLCR;
157 if (bsd_termios->c_iflag & IGNCR)
158 linux_termios->c_iflag |= LINUX_IGNCR;
159 if (bsd_termios->c_iflag & ICRNL)
160 linux_termios->c_iflag |= LINUX_ICRNL;
161 if (bsd_termios->c_iflag & IXON)
162 linux_termios->c_iflag |= LINUX_IXANY;
163 if (bsd_termios->c_iflag & IXON)
164 linux_termios->c_iflag |= LINUX_IXON;
165 if (bsd_termios->c_iflag & IXOFF)
166 linux_termios->c_iflag |= LINUX_IXOFF;
167 if (bsd_termios->c_iflag & IMAXBEL)
168 linux_termios->c_iflag |= LINUX_IMAXBEL;
169
170 linux_termios->c_oflag = 0;
171 if (bsd_termios->c_oflag & OPOST)
172 linux_termios->c_oflag |= LINUX_OPOST;
173 if (bsd_termios->c_oflag & ONLCR)
174 linux_termios->c_oflag |= LINUX_ONLCR;
175 if (bsd_termios->c_oflag & OXTABS)
176 linux_termios->c_oflag |= LINUX_XTABS;
177
178 linux_termios->c_cflag =
179 bsd_to_linux_speed(bsd_termios->c_ispeed, sptab);
180 linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4;
181 if (bsd_termios->c_cflag & CSTOPB)
182 linux_termios->c_cflag |= LINUX_CSTOPB;
183 if (bsd_termios->c_cflag & CREAD)
184 linux_termios->c_cflag |= LINUX_CREAD;
185 if (bsd_termios->c_cflag & PARENB)
186 linux_termios->c_cflag |= LINUX_PARENB;
187 if (bsd_termios->c_cflag & PARODD)
188 linux_termios->c_cflag |= LINUX_PARODD;
189 if (bsd_termios->c_cflag & HUPCL)
190 linux_termios->c_cflag |= LINUX_HUPCL;
191 if (bsd_termios->c_cflag & CLOCAL)
192 linux_termios->c_cflag |= LINUX_CLOCAL;
193 if (bsd_termios->c_cflag & CRTSCTS)
194 linux_termios->c_cflag |= LINUX_CRTSCTS;
195
196 linux_termios->c_lflag = 0;
197 if (bsd_termios->c_lflag & ISIG)
198 linux_termios->c_lflag |= LINUX_ISIG;
199 if (bsd_termios->c_lflag & ICANON)
200 linux_termios->c_lflag |= LINUX_ICANON;
201 if (bsd_termios->c_lflag & ECHO)
202 linux_termios->c_lflag |= LINUX_ECHO;
203 if (bsd_termios->c_lflag & ECHOE)
204 linux_termios->c_lflag |= LINUX_ECHOE;
205 if (bsd_termios->c_lflag & ECHOK)
206 linux_termios->c_lflag |= LINUX_ECHOK;
207 if (bsd_termios->c_lflag & ECHONL)
208 linux_termios->c_lflag |= LINUX_ECHONL;
209 if (bsd_termios->c_lflag & NOFLSH)
210 linux_termios->c_lflag |= LINUX_NOFLSH;
211 if (bsd_termios->c_lflag & TOSTOP)
212 linux_termios->c_lflag |= LINUX_TOSTOP;
213 if (bsd_termios->c_lflag & ECHOCTL)
214 linux_termios->c_lflag |= LINUX_ECHOCTL;
215 if (bsd_termios->c_lflag & ECHOPRT)
216 linux_termios->c_lflag |= LINUX_ECHOPRT;
217 if (bsd_termios->c_lflag & ECHOKE)
218 linux_termios->c_lflag |= LINUX_ECHOKE;
219 if (bsd_termios->c_lflag & FLUSHO)
220 linux_termios->c_lflag |= LINUX_FLUSHO;
221 if (bsd_termios->c_lflag & PENDIN)
222 linux_termios->c_lflag |= LINUX_PENDIN;
223 if (bsd_termios->c_lflag & IEXTEN)
224 linux_termios->c_lflag |= LINUX_IEXTEN;
225
226 for (i=0; i<LINUX_NCCS; i++)
227 linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
228 linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR];
229 linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT];
230 linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE];
231 linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL];
232 linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF];
233 linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL];
234 linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN];
235 linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME];
236 linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2];
237 linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE;
238 linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP];
239 linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART];
240 linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP];
241 linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT];
242 linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD];
243 linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE];
244 linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT];
245
246 for (i=0; i<LINUX_NCCS; i++) {
247 if (linux_termios->c_cc[i] == _POSIX_VDISABLE)
248 linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
249 }
250
251 linux_termios->c_line = 0;
252 #ifdef DEBUG
253 printf("LINUX: LINUX termios structure (output):\n");
254 printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
255 linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
256 linux_termios->c_lflag, linux_termios->c_line);
257 printf("c_cc ");
258 for (i=0; i<LINUX_NCCS; i++)
259 printf("%02x ", linux_termios->c_cc[i]);
260 printf("\n");
261 #endif
262 }
263
264
265 static void
266 linux_to_bsd_termios(struct linux_termios *linux_termios,
267 struct termios *bsd_termios)
268 {
269 int i;
270 #ifdef DEBUG
271 printf("LINUX: LINUX termios structure (input):\n");
272 printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
273 linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
274 linux_termios->c_lflag, linux_termios->c_line);
275 printf("c_cc ");
276 for (i=0; i<LINUX_NCCS; i++)
277 printf("%02x ", linux_termios->c_cc[i]);
278 printf("\n");
279 #endif
280 bsd_termios->c_iflag = 0;
281 if (linux_termios->c_iflag & LINUX_IGNBRK)
282 bsd_termios->c_iflag |= IGNBRK;
283 if (linux_termios->c_iflag & LINUX_BRKINT)
284 bsd_termios->c_iflag |= BRKINT;
285 if (linux_termios->c_iflag & LINUX_IGNPAR)
286 bsd_termios->c_iflag |= IGNPAR;
287 if (linux_termios->c_iflag & LINUX_PARMRK)
288 bsd_termios->c_iflag |= PARMRK;
289 if (linux_termios->c_iflag & LINUX_INPCK)
290 bsd_termios->c_iflag |= INPCK;
291 if (linux_termios->c_iflag & LINUX_ISTRIP)
292 bsd_termios->c_iflag |= ISTRIP;
293 if (linux_termios->c_iflag & LINUX_INLCR)
294 bsd_termios->c_iflag |= INLCR;
295 if (linux_termios->c_iflag & LINUX_IGNCR)
296 bsd_termios->c_iflag |= IGNCR;
297 if (linux_termios->c_iflag & LINUX_ICRNL)
298 bsd_termios->c_iflag |= ICRNL;
299 if (linux_termios->c_iflag & LINUX_IXON)
300 bsd_termios->c_iflag |= IXANY;
301 if (linux_termios->c_iflag & LINUX_IXON)
302 bsd_termios->c_iflag |= IXON;
303 if (linux_termios->c_iflag & LINUX_IXOFF)
304 bsd_termios->c_iflag |= IXOFF;
305 if (linux_termios->c_iflag & LINUX_IMAXBEL)
306 bsd_termios->c_iflag |= IMAXBEL;
307
308 bsd_termios->c_oflag = 0;
309 if (linux_termios->c_oflag & LINUX_OPOST)
310 bsd_termios->c_oflag |= OPOST;
311 if (linux_termios->c_oflag & LINUX_ONLCR)
312 bsd_termios->c_oflag |= ONLCR;
313 if (linux_termios->c_oflag & LINUX_XTABS)
314 bsd_termios->c_oflag |= OXTABS;
315
316 bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4;
317 if (linux_termios->c_cflag & LINUX_CSTOPB)
318 bsd_termios->c_cflag |= CSTOPB;
319 if (linux_termios->c_cflag & LINUX_PARENB)
320 bsd_termios->c_cflag |= PARENB;
321 if (linux_termios->c_cflag & LINUX_PARODD)
322 bsd_termios->c_cflag |= PARODD;
323 if (linux_termios->c_cflag & LINUX_HUPCL)
324 bsd_termios->c_cflag |= HUPCL;
325 if (linux_termios->c_cflag & LINUX_CLOCAL)
326 bsd_termios->c_cflag |= CLOCAL;
327 if (linux_termios->c_cflag & LINUX_CRTSCTS)
328 bsd_termios->c_cflag |= CRTSCTS;
329
330 bsd_termios->c_lflag = 0;
331 if (linux_termios->c_lflag & LINUX_ISIG)
332 bsd_termios->c_lflag |= ISIG;
333 if (linux_termios->c_lflag & LINUX_ICANON)
334 bsd_termios->c_lflag |= ICANON;
335 if (linux_termios->c_lflag & LINUX_ECHO)
336 bsd_termios->c_lflag |= ECHO;
337 if (linux_termios->c_lflag & LINUX_ECHOE)
338 bsd_termios->c_lflag |= ECHOE;
339 if (linux_termios->c_lflag & LINUX_ECHOK)
340 bsd_termios->c_lflag |= ECHOK;
341 if (linux_termios->c_lflag & LINUX_ECHONL)
342 bsd_termios->c_lflag |= ECHONL;
343 if (linux_termios->c_lflag & LINUX_NOFLSH)
344 bsd_termios->c_lflag |= NOFLSH;
345 if (linux_termios->c_lflag & LINUX_TOSTOP)
346 bsd_termios->c_lflag |= TOSTOP;
347 if (linux_termios->c_lflag & LINUX_ECHOCTL)
348 bsd_termios->c_lflag |= ECHOCTL;
349 if (linux_termios->c_lflag & LINUX_ECHOPRT)
350 bsd_termios->c_lflag |= ECHOPRT;
351 if (linux_termios->c_lflag & LINUX_ECHOKE)
352 bsd_termios->c_lflag |= ECHOKE;
353 if (linux_termios->c_lflag & LINUX_FLUSHO)
354 bsd_termios->c_lflag |= FLUSHO;
355 if (linux_termios->c_lflag & LINUX_PENDIN)
356 bsd_termios->c_lflag |= PENDIN;
357 if (linux_termios->c_lflag & IEXTEN)
358 bsd_termios->c_lflag |= IEXTEN;
359
360 for (i=0; i<NCCS; i++)
361 bsd_termios->c_cc[i] = _POSIX_VDISABLE;
362 bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR];
363 bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT];
364 bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE];
365 bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL];
366 bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF];
367 bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL];
368 bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN];
369 bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME];
370 bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2];
371 bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP];
372 bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART];
373 bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP];
374 bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT];
375 bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD];
376 bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE];
377 bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT];
378
379 for (i=0; i<NCCS; i++) {
380 if (bsd_termios->c_cc[i] == LINUX_POSIX_VDISABLE)
381 bsd_termios->c_cc[i] = _POSIX_VDISABLE;
382 }
383
384 bsd_termios->c_ispeed = bsd_termios->c_ospeed =
385 linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab);
386 #ifdef DEBUG
387 printf("LINUX: BSD termios structure (output):\n");
388 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
389 bsd_termios->c_iflag, bsd_termios->c_oflag,
390 bsd_termios->c_cflag, bsd_termios->c_lflag,
391 bsd_termios->c_ispeed, bsd_termios->c_ospeed);
392 printf("c_cc ");
393 for (i=0; i<NCCS; i++)
394 printf("%02x ", bsd_termios->c_cc[i]);
395 printf("\n");
396 #endif
397 }
398
399
400 static void
401 bsd_to_linux_termio(struct termios *bsd_termios,
402 struct linux_termio *linux_termio)
403 {
404 struct linux_termios tmios;
405
406 bsd_to_linux_termios(bsd_termios, &tmios);
407 linux_termio->c_iflag = tmios.c_iflag;
408 linux_termio->c_oflag = tmios.c_oflag;
409 linux_termio->c_cflag = tmios.c_cflag;
410 linux_termio->c_lflag = tmios.c_lflag;
411 linux_termio->c_line = tmios.c_line;
412 memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC);
413 }
414
415 static void
416 linux_to_bsd_termio(struct linux_termio *linux_termio,
417 struct termios *bsd_termios)
418 {
419 struct linux_termios tmios;
420 int i;
421
422 tmios.c_iflag = linux_termio->c_iflag;
423 tmios.c_oflag = linux_termio->c_oflag;
424 tmios.c_cflag = linux_termio->c_cflag;
425 tmios.c_lflag = linux_termio->c_lflag;
426
427 for (i=0; i<LINUX_NCCS; i++)
428 tmios.c_cc[i] = LINUX_POSIX_VDISABLE;
429 memcpy(tmios.c_cc, linux_termio->c_cc, LINUX_NCC);
430
431 linux_to_bsd_termios(&tmios, bsd_termios);
432 }
433
434 static void
435 linux_tiocgserial(struct file *fp, struct linux_serial_struct *lss)
436 {
437 if (!fp || !lss)
438 return;
439
440 lss->type = LINUX_PORT_16550A;
441 lss->flags = 0;
442 lss->close_delay = 0;
443 }
444
445 static void
446 linux_tiocsserial(struct file *fp, struct linux_serial_struct *lss)
447 {
448 if (!fp || !lss)
449 return;
450 }
451
452 int
453 linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval)
454 {
455 struct termios bsd_termios;
456 struct linux_termios linux_termios;
457 struct linux_termio linux_termio;
458 struct filedesc *fdp = p->p_fd;
459 struct file *fp;
460 int (*func)(struct file *fp, int com, caddr_t data, struct proc *p);
461 int bsd_line, linux_line;
462 int error;
463
464 #ifdef DEBUG
465 printf("Linux-emul(%d): ioctl(%d, %04x, *)\n",
466 p->p_pid, args->fd, args->cmd);
467 #endif
468 if ((unsigned)args->fd >= fdp->fd_nfiles
469 || (fp = fdp->fd_ofiles[args->fd]) == 0)
470 return EBADF;
471
472 if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
473 return EBADF;
474 }
475
476 func = fp->f_ops->fo_ioctl;
477 switch (args->cmd & 0xffff) {
478
479 case LINUX_TCGETA:
480 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
481 return error;
482 bsd_to_linux_termio(&bsd_termios, &linux_termio);
483 return copyout((caddr_t)&linux_termio, (caddr_t)args->arg,
484 sizeof(linux_termio));
485
486 case LINUX_TCSETA:
487 linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios);
488 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
489
490 case LINUX_TCSETAW:
491 linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios);
492 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
493
494 case LINUX_TCSETAF:
495 linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios);
496 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
497
498 case LINUX_TCGETS:
499 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
500 return error;
501 bsd_to_linux_termios(&bsd_termios, &linux_termios);
502 return copyout((caddr_t)&linux_termios, (caddr_t)args->arg,
503 sizeof(linux_termios));
504
505 case LINUX_TCSETS:
506 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
507 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
508
509 case LINUX_TCSETSW:
510 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
511 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
512
513 case LINUX_TCSETSF:
514 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
515 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
516
517 case LINUX_TIOCGPGRP:
518 args->cmd = TIOCGPGRP;
519 return ioctl(p, (struct ioctl_args *)args, retval);
520
521 case LINUX_TIOCSPGRP:
522 args->cmd = TIOCSPGRP;
523 return ioctl(p, (struct ioctl_args *)args, retval);
524
525 case LINUX_TIOCGWINSZ:
526 args->cmd = TIOCGWINSZ;
527 return ioctl(p, (struct ioctl_args *)args, retval);
528
529 case LINUX_TIOCSWINSZ:
530 args->cmd = TIOCSWINSZ;
531 return ioctl(p, (struct ioctl_args *)args, retval);
532
533 case LINUX_FIONREAD:
534 args->cmd = FIONREAD;
535 return ioctl(p, (struct ioctl_args *)args, retval);
536
537 case LINUX_FIONBIO:
538 args->cmd = FIONBIO;
539 return ioctl(p, (struct ioctl_args *)args, retval);
540
541 case LINUX_FIOASYNC:
542 args->cmd = FIOASYNC;
543 return ioctl(p, (struct ioctl_args *)args, retval);
544
545 case LINUX_FIONCLEX:
546 args->cmd = FIONCLEX;
547 return ioctl(p, (struct ioctl_args *)args, retval);
548
549 case LINUX_FIOCLEX:
550 args->cmd = FIOCLEX;
551 return ioctl(p, (struct ioctl_args *)args, retval);
552
553 case LINUX_TIOCEXCL:
554 args->cmd = TIOCEXCL;
555 return ioctl(p, (struct ioctl_args *)args, retval);
556
557 case LINUX_TIOCNXCL:
558 args->cmd = TIOCNXCL;
559 return ioctl(p, (struct ioctl_args *)args, retval);
560
561 case LINUX_TIOCCONS:
562 args->cmd = TIOCCONS;
563 return ioctl(p, (struct ioctl_args *)args, retval);
564
565 case LINUX_TIOCNOTTY:
566 args->cmd = TIOCNOTTY;
567 return ioctl(p, (struct ioctl_args *)args, retval);
568
569 case LINUX_SIOCGIFCONF:
570 args->cmd = OSIOCGIFCONF;
571 return ioctl(p, (struct ioctl_args *)args, retval);
572
573 case LINUX_SIOCGIFFLAGS:
574 args->cmd = SIOCGIFFLAGS;
575 return ioctl(p, (struct ioctl_args *)args, retval);
576
577 case LINUX_SIOCGIFADDR:
578 args->cmd = OSIOCGIFADDR;
579 return ioctl(p, (struct ioctl_args *)args, retval);
580
581 case LINUX_SIOCGIFDSTADDR:
582 args->cmd = OSIOCGIFDSTADDR;
583 return ioctl(p, (struct ioctl_args *)args, retval);
584
585 case LINUX_SIOCGIFBRDADDR:
586 args->cmd = OSIOCGIFBRDADDR;
587 return ioctl(p, (struct ioctl_args *)args, retval);
588
589 case LINUX_SIOCGIFNETMASK:
590 args->cmd = OSIOCGIFNETMASK;
591 return ioctl(p, (struct ioctl_args *)args, retval);
592
593 /* get hardware address */
594 case LINUX_SIOCGIFHWADDR:
595 {
596 int ifn;
597 struct ifnet *ifp;
598 struct ifaddr *ifa;
599 struct sockaddr_dl *sdl;
600 struct linux_ifreq *ifr = (struct linux_ifreq *)args->arg;
601
602 /*
603 * Note that we don't actually respect the name in the ifreq structure, as
604 * Linux interface names are all different
605 */
606
607 for (ifn = 0; ifn < if_index; ifn++) {
608
609 ifp = ifnet_addrs[ifn]->ifa_ifp; /* pointer to interface */
610 if (ifp->if_type == IFT_ETHER) { /* looks good */
611 /* walk the address list */
612 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
613 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && /* we have an address structure */
614 (sdl->sdl_family == AF_LINK) && /* it's a link address */
615 (sdl->sdl_type == IFT_ETHER)) { /* for an ethernet link */
616
617 return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_IFHWADDRLEN));
618 }
619 }
620 }
621 }
622 return(ENOENT); /* ??? */
623 }
624
625 case LINUX_SIOCADDMULTI:
626 args->cmd = SIOCADDMULTI;
627 return ioctl(p, (struct ioctl_args *)args, retval);
628
629 case LINUX_SIOCDELMULTI:
630 args->cmd = SIOCDELMULTI;
631 return ioctl(p, (struct ioctl_args *)args, retval);
632
633 case LINUX_TIOCSETD:
634 switch (args->arg) {
635 case LINUX_N_TTY:
636 bsd_line = TTYDISC;
637 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
638 case LINUX_N_SLIP:
639 bsd_line = SLIPDISC;
640 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
641 case LINUX_N_PPP:
642 bsd_line = PPPDISC;
643 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
644 default:
645 return EINVAL;
646 }
647
648 case LINUX_TIOCGETD:
649 bsd_line = TTYDISC;
650 if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p))
651 return error;
652 switch (bsd_line) {
653 case TTYDISC:
654 linux_line = LINUX_N_TTY;
655 break;
656 case SLIPDISC:
657 linux_line = LINUX_N_SLIP;
658 break;
659 case PPPDISC:
660 linux_line = LINUX_N_PPP;
661 break;
662 default:
663 return EINVAL;
664 }
665 return copyout(&linux_line, (caddr_t)args->arg,
666 sizeof(int));
667
668 case LINUX_SNDCTL_SEQ_RESET:
669 args->cmd = SNDCTL_SEQ_RESET;
670 return ioctl(p, (struct ioctl_args *)args, retval);
671 case LINUX_SNDCTL_SEQ_SYNC:
672 args->cmd = SNDCTL_SEQ_SYNC;
673 return ioctl(p, (struct ioctl_args *)args, retval);
674 case LINUX_SNDCTL_SYNTH_INFO:
675 args->cmd = SNDCTL_SYNTH_INFO;
676 return ioctl(p, (struct ioctl_args *)args, retval);
677 case LINUX_SNDCTL_SEQ_CTRLRATE:
678 args->cmd = SNDCTL_SEQ_CTRLRATE;
679 return ioctl(p, (struct ioctl_args *)args, retval);
680 case LINUX_SNDCTL_SEQ_GETOUTCOUNT:
681 args->cmd = SNDCTL_SEQ_GETOUTCOUNT;
682 return ioctl(p, (struct ioctl_args *)args, retval);
683 case LINUX_SNDCTL_SEQ_GETINCOUNT:
684 args->cmd = SNDCTL_SEQ_GETINCOUNT;
685 return ioctl(p, (struct ioctl_args *)args, retval);
686 case LINUX_SNDCTL_SEQ_PERCMODE:
687 args->cmd = SNDCTL_SEQ_PERCMODE;
688 return ioctl(p, (struct ioctl_args *)args, retval);
689 case LINUX_SNDCTL_FM_LOAD_INSTR:
690 args->cmd = SNDCTL_FM_LOAD_INSTR;
691 return ioctl(p, (struct ioctl_args *)args, retval);
692 case LINUX_SNDCTL_SEQ_TESTMIDI:
693 args->cmd = SNDCTL_SEQ_TESTMIDI;
694 return ioctl(p, (struct ioctl_args *)args, retval);
695 case LINUX_SNDCTL_SEQ_RESETSAMPLES:
696 args->cmd = SNDCTL_SEQ_RESETSAMPLES;
697 return ioctl(p, (struct ioctl_args *)args, retval);
698 case LINUX_SNDCTL_SEQ_NRSYNTHS:
699 args->cmd = SNDCTL_SEQ_NRSYNTHS;
700 return ioctl(p, (struct ioctl_args *)args, retval);
701 case LINUX_SNDCTL_SEQ_NRMIDIS:
702 args->cmd = SNDCTL_SEQ_NRMIDIS;
703 return ioctl(p, (struct ioctl_args *)args, retval);
704 case LINUX_SNDCTL_MIDI_INFO:
705 args->cmd = SNDCTL_MIDI_INFO;
706 return ioctl(p, (struct ioctl_args *)args, retval);
707 case LINUX_SNDCTL_SEQ_TRESHOLD:
708 args->cmd = SNDCTL_SEQ_TRESHOLD;
709 return ioctl(p, (struct ioctl_args *)args, retval);
710 case LINUX_SNDCTL_SYNTH_MEMAVL:
711 args->cmd = SNDCTL_SYNTH_MEMAVL;
712 return ioctl(p, (struct ioctl_args *)args, retval);
713 case LINUX_SNDCTL_DSP_GETOPTR :
714 args->cmd = SNDCTL_DSP_GETOPTR;
715 return ioctl(p, (struct ioctl_args *)args, retval);
716
717 case LINUX_SNDCTL_DSP_GETIPTR :
718 args->cmd = SNDCTL_DSP_GETIPTR;
719 return ioctl(p, (struct ioctl_args *)args, retval);
720
721 case LINUX_SNDCTL_DSP_SETTRIGGER:
722 args->cmd = SNDCTL_DSP_SETTRIGGER;
723 return ioctl(p, (struct ioctl_args *)args, retval);
724
725 case LINUX_SNDCTL_DSP_GETCAPS:
726 args->cmd = SNDCTL_DSP_GETCAPS;
727 return ioctl(p, (struct ioctl_args *)args, retval);
728
729 case LINUX_SNDCTL_DSP_RESET:
730 args->cmd = SNDCTL_DSP_RESET;
731 return ioctl(p, (struct ioctl_args *)args, retval);
732
733 case LINUX_SNDCTL_DSP_SYNC:
734 args->cmd = SNDCTL_DSP_SYNC;
735 return ioctl(p, (struct ioctl_args *)args, retval);
736
737 case LINUX_SNDCTL_DSP_SPEED:
738 args->cmd = SNDCTL_DSP_SPEED;
739 return ioctl(p, (struct ioctl_args *)args, retval);
740
741 case LINUX_SNDCTL_DSP_STEREO:
742 args->cmd = SNDCTL_DSP_STEREO;
743 return ioctl(p, (struct ioctl_args *)args, retval);
744
745 case LINUX_SNDCTL_DSP_GETBLKSIZE:
746 /* LINUX_SNDCTL_DSP_SETBLKSIZE */
747 args->cmd = SNDCTL_DSP_GETBLKSIZE;
748 return ioctl(p, (struct ioctl_args *)args, retval);
749
750 case LINUX_SNDCTL_DSP_SETFMT:
751 args->cmd = SNDCTL_DSP_SETFMT;
752 return ioctl(p, (struct ioctl_args *)args, retval);
753
754 case LINUX_SOUND_PCM_WRITE_CHANNELS:
755 args->cmd = SOUND_PCM_WRITE_CHANNELS;
756 return ioctl(p, (struct ioctl_args *)args, retval);
757
758 case LINUX_SOUND_PCM_WRITE_FILTER:
759 args->cmd = SOUND_PCM_WRITE_FILTER;
760 return ioctl(p, (struct ioctl_args *)args, retval);
761
762 case LINUX_SNDCTL_DSP_POST:
763 args->cmd = SNDCTL_DSP_POST;
764 return ioctl(p, (struct ioctl_args *)args, retval);
765
766 case LINUX_SNDCTL_DSP_SUBDIVIDE:
767 args->cmd = SNDCTL_DSP_SUBDIVIDE;
768 return ioctl(p, (struct ioctl_args *)args, retval);
769
770 case LINUX_SNDCTL_DSP_SETFRAGMENT:
771 args->cmd = SNDCTL_DSP_SETFRAGMENT;
772 return ioctl(p, (struct ioctl_args *)args, retval);
773
774 case LINUX_SNDCTL_DSP_GETFMTS:
775 args->cmd = SNDCTL_DSP_GETFMTS;
776 return ioctl(p, (struct ioctl_args *)args, retval);
777
778 case LINUX_SNDCTL_DSP_GETOSPACE:
779 args->cmd = SNDCTL_DSP_GETOSPACE;
780 return ioctl(p, (struct ioctl_args *)args, retval);
781
782 case LINUX_SNDCTL_DSP_GETISPACE:
783 args->cmd = SNDCTL_DSP_GETISPACE;
784 return ioctl(p, (struct ioctl_args *)args, retval);
785
786 case LINUX_SNDCTL_DSP_NONBLOCK:
787 args->cmd = SNDCTL_DSP_NONBLOCK;
788 return ioctl(p, (struct ioctl_args *)args, retval);
789
790 case LINUX_SOUND_MIXER_WRITE_VOLUME:
791 args->cmd = SOUND_MIXER_WRITE_VOLUME;
792 return ioctl(p, (struct ioctl_args *)args, retval);
793
794 case LINUX_SOUND_MIXER_WRITE_BASS:
795 args->cmd = SOUND_MIXER_WRITE_BASS;
796 return ioctl(p, (struct ioctl_args *)args, retval);
797
798 case LINUX_SOUND_MIXER_WRITE_TREBLE:
799 args->cmd = SOUND_MIXER_WRITE_TREBLE;
800 return ioctl(p, (struct ioctl_args *)args, retval);
801
802 case LINUX_SOUND_MIXER_WRITE_SYNTH:
803 args->cmd = SOUND_MIXER_WRITE_SYNTH;
804 return ioctl(p, (struct ioctl_args *)args, retval);
805
806 case LINUX_SOUND_MIXER_WRITE_PCM:
807 args->cmd = SOUND_MIXER_WRITE_PCM;
808 return ioctl(p, (struct ioctl_args *)args, retval);
809
810 case LINUX_SOUND_MIXER_WRITE_SPEAKER:
811 args->cmd = SOUND_MIXER_WRITE_SPEAKER;
812 return ioctl(p, (struct ioctl_args *)args, retval);
813
814 case LINUX_SOUND_MIXER_WRITE_LINE:
815 args->cmd = SOUND_MIXER_WRITE_LINE;
816 return ioctl(p, (struct ioctl_args *)args, retval);
817
818 case LINUX_SOUND_MIXER_WRITE_MIC:
819 args->cmd = SOUND_MIXER_WRITE_MIC;
820 return ioctl(p, (struct ioctl_args *)args, retval);
821
822 case LINUX_SOUND_MIXER_WRITE_CD:
823 args->cmd = SOUND_MIXER_WRITE_CD;
824 return ioctl(p, (struct ioctl_args *)args, retval);
825
826 case LINUX_SOUND_MIXER_WRITE_IMIX:
827 args->cmd = SOUND_MIXER_WRITE_IMIX;
828 return ioctl(p, (struct ioctl_args *)args, retval);
829
830 case LINUX_SOUND_MIXER_WRITE_ALTPCM:
831 args->cmd = SOUND_MIXER_WRITE_ALTPCM;
832 return ioctl(p, (struct ioctl_args *)args, retval);
833
834 case LINUX_SOUND_MIXER_WRITE_RECLEV:
835 args->cmd = SOUND_MIXER_WRITE_RECLEV;
836 return ioctl(p, (struct ioctl_args *)args, retval);
837
838 case LINUX_SOUND_MIXER_WRITE_IGAIN:
839 args->cmd = SOUND_MIXER_WRITE_IGAIN;
840 return ioctl(p, (struct ioctl_args *)args, retval);
841
842 case LINUX_SOUND_MIXER_WRITE_OGAIN:
843 args->cmd = SOUND_MIXER_WRITE_OGAIN;
844 return ioctl(p, (struct ioctl_args *)args, retval);
845
846 case LINUX_SOUND_MIXER_WRITE_LINE1:
847 args->cmd = SOUND_MIXER_WRITE_LINE1;
848 return ioctl(p, (struct ioctl_args *)args, retval);
849
850 case LINUX_SOUND_MIXER_WRITE_LINE2:
851 args->cmd = SOUND_MIXER_WRITE_LINE2;
852 return ioctl(p, (struct ioctl_args *)args, retval);
853
854 case LINUX_SOUND_MIXER_WRITE_LINE3:
855 args->cmd = SOUND_MIXER_WRITE_LINE3;
856 return ioctl(p, (struct ioctl_args *)args, retval);
857
858 case LINUX_SOUND_MIXER_READ_DEVMASK:
859 args->cmd = SOUND_MIXER_READ_DEVMASK;
860 return ioctl(p, (struct ioctl_args *)args, retval);
861
862 case LINUX_TIOCGSERIAL:
863 linux_tiocgserial(fp, (struct linux_serial_struct *)args->arg);
864 return 0;
865
866 case LINUX_TIOCSSERIAL:
867 linux_tiocsserial(fp, (struct linux_serial_struct *)args->arg);
868 return 0;
869
870 case LINUX_TCFLSH:
871 args->cmd = TIOCFLUSH;
872 switch (args->arg) {
873 case LINUX_TCIFLUSH:
874 args->arg = FREAD;
875 break;
876 case LINUX_TCOFLUSH:
877 args->arg = FWRITE;
878 break;
879 case LINUX_TCIOFLUSH:
880 args->arg = FREAD | FWRITE;
881 break;
882 default:
883 return EINVAL;
884 }
885 return ioctl(p, (struct ioctl_args *)args, retval);
886
887 case LINUX_VT_OPENQRY:
888
889 args->cmd = VT_OPENQRY;
890 return ioctl(p, (struct ioctl_args *)args, retval);
891
892 case LINUX_VT_GETMODE:
893
894 args->cmd = VT_GETMODE;
895 return ioctl(p, (struct ioctl_args *)args, retval);
896
897 case LINUX_VT_SETMODE:
898 {
899 struct vt_mode *mode;
900 args->cmd = VT_SETMODE;
901 mode = (struct vt_mode *)args->arg;
902 if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig))
903 mode->frsig = mode->acqsig;
904 return ioctl(p, (struct ioctl_args *)args, retval);
905 }
906
907 case LINUX_VT_GETSTATE:
908
909 args->cmd = VT_GETACTIVE;
910 return ioctl(p, (struct ioctl_args *)args, retval);
911
912 case LINUX_VT_ACTIVATE:
913
914 args->cmd = VT_ACTIVATE;
915 return ioctl(p, (struct ioctl_args *)args, retval);
916
917 case LINUX_VT_WAITACTIVE:
918
919 args->cmd = VT_WAITACTIVE;
920 return ioctl(p, (struct ioctl_args *)args, retval);
921
922 case LINUX_KDGKBMODE:
923
924 args->cmd = KDGKBMODE;
925 return ioctl(p, (struct ioctl_args *)args, retval);
926
927 case LINUX_KDSKBMODE:
928 {
929 int kbdmode;
930 switch (args->arg) {
931 case LINUX_KBD_RAW:
932 kbdmode = K_RAW;
933 return (*func)(fp, KDSKBMODE, (caddr_t)&kbdmode, p);
934 case LINUX_KBD_XLATE:
935 kbdmode = K_XLATE;
936 return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
937 case LINUX_KBD_MEDIUMRAW:
938 kbdmode = K_RAW;
939 return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
940 default:
941 return EINVAL;
942 }
943 }
944
945 case LINUX_KDGETMODE:
946 args->cmd = KDGETMODE;
947 return ioctl(p, (struct ioctl_args *)args, retval);
948
949 case LINUX_KDSETMODE:
950 args->cmd = KDSETMODE;
951 return ioctl(p, (struct ioctl_args *)args, retval);
952
953 case LINUX_KDSETLED:
954 args->cmd = KDSETLED;
955 return ioctl(p, (struct ioctl_args *)args, retval);
956
957 case LINUX_KDGETLED:
958 args->cmd = KDGETLED;
959 return ioctl(p, (struct ioctl_args *)args, retval);
960
961 case LINUX_KIOCSOUND:
962 args->cmd = KIOCSOUND;
963 return ioctl(p, (struct ioctl_args *)args, retval);
964
965 case LINUX_KDMKTONE:
966 args->cmd = KDMKTONE;
967 return ioctl(p, (struct ioctl_args *)args, retval);
968 }
969
970 uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
971 args->fd, (u_int)((args->cmd & 0xffff00) >> 8),
972 (int)((args->cmd & 0xffff00) >> 8), (u_int)(args->cmd & 0xff));
973 return EINVAL;
974 }
Cache object: e698998a182b7a00df2d14d32a6ba08d
|