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$
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 #include <i386/linux/linux_util.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 int c_iflag;
68 unsigned int c_oflag;
69 unsigned int c_cflag;
70 unsigned int 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 { B0, LINUX_B0 }, { B50, LINUX_B50 },
82 { B75, LINUX_B75 }, { B110, LINUX_B110 },
83 { B134, LINUX_B134 }, { B150, LINUX_B150 },
84 { B200, LINUX_B200 }, { B300, LINUX_B300 },
85 { B600, LINUX_B600 }, { B1200, LINUX_B1200 },
86 { B1800, LINUX_B1800 }, { B2400, LINUX_B2400 },
87 { B4800, LINUX_B4800 }, { B9600, LINUX_B9600 },
88 { B19200, LINUX_B19200 }, { B38400, LINUX_B38400 },
89 { B57600, LINUX_B57600 }, { B115200, LINUX_B115200 },
90 {-1, -1 }
91 };
92
93 struct linux_serial_struct {
94 int type;
95 int line;
96 int port;
97 int irq;
98 int flags;
99 int xmit_fifo_size;
100 int custom_divisor;
101 int baud_base;
102 unsigned short close_delay;
103 char reserved_char[2];
104 int hub6;
105 unsigned short closing_wait;
106 unsigned short closing_wait2;
107 int reserved[4];
108 };
109
110 struct linux_cdrom_msf
111 {
112 u_char cdmsf_min0;
113 u_char cdmsf_sec0;
114 u_char cdmsf_frame0;
115 u_char cdmsf_min1;
116 u_char cdmsf_sec1;
117 u_char cdmsf_frame1;
118 };
119
120 struct linux_cdrom_tochdr
121 {
122 u_char cdth_trk0;
123 u_char cdth_trk1;
124 };
125
126 union linux_cdrom_addr
127 {
128 struct {
129 u_char minute;
130 u_char second;
131 u_char frame;
132 } msf;
133 int lba;
134 };
135
136 struct linux_cdrom_tocentry
137 {
138 u_char cdte_track;
139 u_char cdte_adr:4;
140 u_char cdte_ctrl:4;
141 u_char cdte_format;
142 union linux_cdrom_addr cdte_addr;
143 u_char cdte_datamode;
144 };
145
146 struct linux_cdrom_subchnl
147 {
148 u_char cdsc_format;
149 u_char cdsc_audiostatus;
150 u_char cdsc_adr:4;
151 u_char cdsc_ctrl:4;
152 u_char cdsc_trk;
153 u_char cdsc_ind;
154 union linux_cdrom_addr cdsc_absaddr;
155 union linux_cdrom_addr cdsc_reladdr;
156 };
157
158
159 static int
160 linux_to_bsd_speed(int code, struct speedtab *table)
161 {
162 for ( ; table->sp_code != -1; table++)
163 if (table->sp_code == code)
164 return (table->sp_speed);
165 return -1;
166 }
167
168 static int
169 bsd_to_linux_speed(int speed, struct speedtab *table)
170 {
171 for ( ; table->sp_speed != -1; table++)
172 if (table->sp_speed == speed)
173 return (table->sp_code);
174 return -1;
175 }
176
177 static void
178 bsd_to_linux_termios(struct termios *bsd_termios,
179 struct linux_termios *linux_termios)
180 {
181 int i;
182
183 #ifdef DEBUG
184 printf("LINUX: BSD termios structure (input):\n");
185 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
186 bsd_termios->c_iflag, bsd_termios->c_oflag,
187 bsd_termios->c_cflag, bsd_termios->c_lflag,
188 bsd_termios->c_ispeed, bsd_termios->c_ospeed);
189 printf("c_cc ");
190 for (i=0; i<NCCS; i++)
191 printf("%02x ", bsd_termios->c_cc[i]);
192 printf("\n");
193 #endif
194 linux_termios->c_iflag = 0;
195 if (bsd_termios->c_iflag & IGNBRK)
196 linux_termios->c_iflag |= LINUX_IGNBRK;
197 if (bsd_termios->c_iflag & BRKINT)
198 linux_termios->c_iflag |= LINUX_BRKINT;
199 if (bsd_termios->c_iflag & IGNPAR)
200 linux_termios->c_iflag |= LINUX_IGNPAR;
201 if (bsd_termios->c_iflag & PARMRK)
202 linux_termios->c_iflag |= LINUX_PARMRK;
203 if (bsd_termios->c_iflag & INPCK)
204 linux_termios->c_iflag |= LINUX_INPCK;
205 if (bsd_termios->c_iflag & ISTRIP)
206 linux_termios->c_iflag |= LINUX_ISTRIP;
207 if (bsd_termios->c_iflag & INLCR)
208 linux_termios->c_iflag |= LINUX_INLCR;
209 if (bsd_termios->c_iflag & IGNCR)
210 linux_termios->c_iflag |= LINUX_IGNCR;
211 if (bsd_termios->c_iflag & ICRNL)
212 linux_termios->c_iflag |= LINUX_ICRNL;
213 if (bsd_termios->c_iflag & IXON)
214 linux_termios->c_iflag |= LINUX_IXON;
215 if (bsd_termios->c_iflag & IXANY)
216 linux_termios->c_iflag |= LINUX_IXANY;
217 if (bsd_termios->c_iflag & IXOFF)
218 linux_termios->c_iflag |= LINUX_IXOFF;
219 if (bsd_termios->c_iflag & IMAXBEL)
220 linux_termios->c_iflag |= LINUX_IMAXBEL;
221
222 linux_termios->c_oflag = 0;
223 if (bsd_termios->c_oflag & OPOST)
224 linux_termios->c_oflag |= LINUX_OPOST;
225 if (bsd_termios->c_oflag & ONLCR)
226 linux_termios->c_oflag |= LINUX_ONLCR;
227 if (bsd_termios->c_oflag & OXTABS)
228 linux_termios->c_oflag |= LINUX_XTABS;
229
230 linux_termios->c_cflag =
231 bsd_to_linux_speed(bsd_termios->c_ispeed, sptab);
232 linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4;
233 if (bsd_termios->c_cflag & CSTOPB)
234 linux_termios->c_cflag |= LINUX_CSTOPB;
235 if (bsd_termios->c_cflag & CREAD)
236 linux_termios->c_cflag |= LINUX_CREAD;
237 if (bsd_termios->c_cflag & PARENB)
238 linux_termios->c_cflag |= LINUX_PARENB;
239 if (bsd_termios->c_cflag & PARODD)
240 linux_termios->c_cflag |= LINUX_PARODD;
241 if (bsd_termios->c_cflag & HUPCL)
242 linux_termios->c_cflag |= LINUX_HUPCL;
243 if (bsd_termios->c_cflag & CLOCAL)
244 linux_termios->c_cflag |= LINUX_CLOCAL;
245 if (bsd_termios->c_cflag & CRTSCTS)
246 linux_termios->c_cflag |= LINUX_CRTSCTS;
247
248 linux_termios->c_lflag = 0;
249 if (bsd_termios->c_lflag & ISIG)
250 linux_termios->c_lflag |= LINUX_ISIG;
251 if (bsd_termios->c_lflag & ICANON)
252 linux_termios->c_lflag |= LINUX_ICANON;
253 if (bsd_termios->c_lflag & ECHO)
254 linux_termios->c_lflag |= LINUX_ECHO;
255 if (bsd_termios->c_lflag & ECHOE)
256 linux_termios->c_lflag |= LINUX_ECHOE;
257 if (bsd_termios->c_lflag & ECHOK)
258 linux_termios->c_lflag |= LINUX_ECHOK;
259 if (bsd_termios->c_lflag & ECHONL)
260 linux_termios->c_lflag |= LINUX_ECHONL;
261 if (bsd_termios->c_lflag & NOFLSH)
262 linux_termios->c_lflag |= LINUX_NOFLSH;
263 if (bsd_termios->c_lflag & TOSTOP)
264 linux_termios->c_lflag |= LINUX_TOSTOP;
265 if (bsd_termios->c_lflag & ECHOCTL)
266 linux_termios->c_lflag |= LINUX_ECHOCTL;
267 if (bsd_termios->c_lflag & ECHOPRT)
268 linux_termios->c_lflag |= LINUX_ECHOPRT;
269 if (bsd_termios->c_lflag & ECHOKE)
270 linux_termios->c_lflag |= LINUX_ECHOKE;
271 if (bsd_termios->c_lflag & FLUSHO)
272 linux_termios->c_lflag |= LINUX_FLUSHO;
273 if (bsd_termios->c_lflag & PENDIN)
274 linux_termios->c_lflag |= LINUX_PENDIN;
275 if (bsd_termios->c_lflag & IEXTEN)
276 linux_termios->c_lflag |= LINUX_IEXTEN;
277
278 for (i=0; i<LINUX_NCCS; i++)
279 linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
280 linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR];
281 linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT];
282 linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE];
283 linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL];
284 linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF];
285 linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL];
286 linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN];
287 linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME];
288 linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2];
289 linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP];
290 linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART];
291 linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP];
292 linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT];
293 linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD];
294 linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE];
295 linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT];
296
297 for (i=0; i<LINUX_NCCS; i++) {
298 if (linux_termios->c_cc[i] == _POSIX_VDISABLE)
299 linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
300 }
301
302 linux_termios->c_line = 0;
303 #ifdef DEBUG
304 printf("LINUX: LINUX termios structure (output):\n");
305 printf("i=%08lx o=%08lx c=%08lx l=%08lx line=%d\n",
306 linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
307 linux_termios->c_lflag, linux_termios->c_line);
308 printf("c_cc ");
309 for (i=0; i<LINUX_NCCS; i++)
310 printf("%02x ", linux_termios->c_cc[i]);
311 printf("\n");
312 #endif
313 }
314
315
316 static void
317 linux_to_bsd_termios(struct linux_termios *linux_termios,
318 struct termios *bsd_termios)
319 {
320 int i;
321 #ifdef DEBUG
322 printf("LINUX: LINUX termios structure (input):\n");
323 printf("i=%08lx o=%08lx c=%08lx l=%08lx line=%d\n",
324 linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
325 linux_termios->c_lflag, linux_termios->c_line);
326 printf("c_cc ");
327 for (i=0; i<LINUX_NCCS; i++)
328 printf("%02x ", linux_termios->c_cc[i]);
329 printf("\n");
330 #endif
331 bsd_termios->c_iflag = 0;
332 if (linux_termios->c_iflag & LINUX_IGNBRK)
333 bsd_termios->c_iflag |= IGNBRK;
334 if (linux_termios->c_iflag & LINUX_BRKINT)
335 bsd_termios->c_iflag |= BRKINT;
336 if (linux_termios->c_iflag & LINUX_IGNPAR)
337 bsd_termios->c_iflag |= IGNPAR;
338 if (linux_termios->c_iflag & LINUX_PARMRK)
339 bsd_termios->c_iflag |= PARMRK;
340 if (linux_termios->c_iflag & LINUX_INPCK)
341 bsd_termios->c_iflag |= INPCK;
342 if (linux_termios->c_iflag & LINUX_ISTRIP)
343 bsd_termios->c_iflag |= ISTRIP;
344 if (linux_termios->c_iflag & LINUX_INLCR)
345 bsd_termios->c_iflag |= INLCR;
346 if (linux_termios->c_iflag & LINUX_IGNCR)
347 bsd_termios->c_iflag |= IGNCR;
348 if (linux_termios->c_iflag & LINUX_ICRNL)
349 bsd_termios->c_iflag |= ICRNL;
350 if (linux_termios->c_iflag & LINUX_IXON)
351 bsd_termios->c_iflag |= IXON;
352 if (linux_termios->c_iflag & LINUX_IXANY)
353 bsd_termios->c_iflag |= IXANY;
354 if (linux_termios->c_iflag & LINUX_IXOFF)
355 bsd_termios->c_iflag |= IXOFF;
356 if (linux_termios->c_iflag & LINUX_IMAXBEL)
357 bsd_termios->c_iflag |= IMAXBEL;
358
359 bsd_termios->c_oflag = 0;
360 if (linux_termios->c_oflag & LINUX_OPOST)
361 bsd_termios->c_oflag |= OPOST;
362 if (linux_termios->c_oflag & LINUX_ONLCR)
363 bsd_termios->c_oflag |= ONLCR;
364 if (linux_termios->c_oflag & LINUX_XTABS)
365 bsd_termios->c_oflag |= OXTABS;
366
367 bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4;
368 if (linux_termios->c_cflag & LINUX_CSTOPB)
369 bsd_termios->c_cflag |= CSTOPB;
370 if (linux_termios->c_cflag & LINUX_CREAD)
371 bsd_termios->c_cflag |= CREAD;
372 if (linux_termios->c_cflag & LINUX_PARENB)
373 bsd_termios->c_cflag |= PARENB;
374 if (linux_termios->c_cflag & LINUX_PARODD)
375 bsd_termios->c_cflag |= PARODD;
376 if (linux_termios->c_cflag & LINUX_HUPCL)
377 bsd_termios->c_cflag |= HUPCL;
378 if (linux_termios->c_cflag & LINUX_CLOCAL)
379 bsd_termios->c_cflag |= CLOCAL;
380 if (linux_termios->c_cflag & LINUX_CRTSCTS)
381 bsd_termios->c_cflag |= CRTSCTS;
382
383 bsd_termios->c_lflag = 0;
384 if (linux_termios->c_lflag & LINUX_ISIG)
385 bsd_termios->c_lflag |= ISIG;
386 if (linux_termios->c_lflag & LINUX_ICANON)
387 bsd_termios->c_lflag |= ICANON;
388 if (linux_termios->c_lflag & LINUX_ECHO)
389 bsd_termios->c_lflag |= ECHO;
390 if (linux_termios->c_lflag & LINUX_ECHOE)
391 bsd_termios->c_lflag |= ECHOE;
392 if (linux_termios->c_lflag & LINUX_ECHOK)
393 bsd_termios->c_lflag |= ECHOK;
394 if (linux_termios->c_lflag & LINUX_ECHONL)
395 bsd_termios->c_lflag |= ECHONL;
396 if (linux_termios->c_lflag & LINUX_NOFLSH)
397 bsd_termios->c_lflag |= NOFLSH;
398 if (linux_termios->c_lflag & LINUX_TOSTOP)
399 bsd_termios->c_lflag |= TOSTOP;
400 if (linux_termios->c_lflag & LINUX_ECHOCTL)
401 bsd_termios->c_lflag |= ECHOCTL;
402 if (linux_termios->c_lflag & LINUX_ECHOPRT)
403 bsd_termios->c_lflag |= ECHOPRT;
404 if (linux_termios->c_lflag & LINUX_ECHOKE)
405 bsd_termios->c_lflag |= ECHOKE;
406 if (linux_termios->c_lflag & LINUX_FLUSHO)
407 bsd_termios->c_lflag |= FLUSHO;
408 if (linux_termios->c_lflag & LINUX_PENDIN)
409 bsd_termios->c_lflag |= PENDIN;
410 if (linux_termios->c_lflag & LINUX_IEXTEN)
411 bsd_termios->c_lflag |= IEXTEN;
412
413 for (i=0; i<NCCS; i++)
414 bsd_termios->c_cc[i] = _POSIX_VDISABLE;
415 bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR];
416 bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT];
417 bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE];
418 bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL];
419 bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF];
420 bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL];
421 bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN];
422 bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME];
423 bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2];
424 bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP];
425 bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART];
426 bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP];
427 bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT];
428 bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD];
429 bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE];
430 bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT];
431
432 for (i=0; i<NCCS; i++) {
433 if (bsd_termios->c_cc[i] == LINUX_POSIX_VDISABLE)
434 bsd_termios->c_cc[i] = _POSIX_VDISABLE;
435 }
436
437 bsd_termios->c_ispeed = bsd_termios->c_ospeed =
438 linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab);
439 #ifdef DEBUG
440 printf("LINUX: BSD termios structure (output):\n");
441 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
442 bsd_termios->c_iflag, bsd_termios->c_oflag,
443 bsd_termios->c_cflag, bsd_termios->c_lflag,
444 bsd_termios->c_ispeed, bsd_termios->c_ospeed);
445 printf("c_cc ");
446 for (i=0; i<NCCS; i++)
447 printf("%02x ", bsd_termios->c_cc[i]);
448 printf("\n");
449 #endif
450 }
451
452
453 static void
454 bsd_to_linux_termio(struct termios *bsd_termios,
455 struct linux_termio *linux_termio)
456 {
457 struct linux_termios tmios;
458
459 bsd_to_linux_termios(bsd_termios, &tmios);
460 linux_termio->c_iflag = tmios.c_iflag;
461 linux_termio->c_oflag = tmios.c_oflag;
462 linux_termio->c_cflag = tmios.c_cflag;
463 linux_termio->c_lflag = tmios.c_lflag;
464 linux_termio->c_line = tmios.c_line;
465 memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC);
466 }
467
468 static void
469 linux_to_bsd_termio(struct linux_termio *linux_termio,
470 struct termios *bsd_termios)
471 {
472 struct linux_termios tmios;
473 int i;
474
475 tmios.c_iflag = linux_termio->c_iflag;
476 tmios.c_oflag = linux_termio->c_oflag;
477 tmios.c_cflag = linux_termio->c_cflag;
478 tmios.c_lflag = linux_termio->c_lflag;
479
480 for (i=LINUX_NCC; i<LINUX_NCCS; i++)
481 tmios.c_cc[i] = LINUX_POSIX_VDISABLE;
482 memcpy(tmios.c_cc, linux_termio->c_cc, LINUX_NCC);
483
484 linux_to_bsd_termios(&tmios, bsd_termios);
485 }
486
487 static void
488 bsd_to_linux_msf_lba(u_char address_format,
489 union msf_lba *bp, union linux_cdrom_addr *lp)
490 {
491 if (address_format == CD_LBA_FORMAT)
492 lp->lba = bp->lba;
493 else {
494 lp->msf.minute = bp->msf.minute;
495 lp->msf.second = bp->msf.second;
496 lp->msf.frame = bp->msf.frame;
497 }
498 }
499
500 static void
501 set_linux_cdrom_addr(union linux_cdrom_addr *addr, int format, int lba)
502 {
503 if (format == LINUX_CDROM_MSF) {
504 addr->msf.frame = lba % 75;
505 lba /= 75;
506 lba += 2;
507 addr->msf.second = lba % 60;
508 addr->msf.minute = lba / 60;
509 }
510 else
511 addr->lba = lba;
512 }
513
514 static unsigned dirbits[4] = { IOC_VOID, IOC_IN, IOC_OUT, IOC_INOUT };
515
516 #define SETDIR(c) (((c) & ~IOC_DIRMASK) | dirbits[args->cmd >> 30])
517
518 int
519 linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
520 {
521 struct termios bsd_termios;
522 struct linux_termios linux_termios;
523 struct linux_termio linux_termio;
524 struct filedesc *fdp = p->p_fd;
525 struct file *fp;
526 int (*func)(struct file *fp, u_long com, caddr_t data, struct proc *p);
527 int bsd_line, linux_line;
528 int error;
529
530 #ifdef DEBUG
531 printf("Linux-emul(%ld): ioctl(%d, %04lx, *)\n",
532 (long)p->p_pid, args->fd, args->cmd);
533 #endif
534 if ((unsigned)args->fd >= fdp->fd_nfiles
535 || (fp = fdp->fd_ofiles[args->fd]) == 0)
536 return EBADF;
537
538 if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
539 return EBADF;
540 }
541
542 func = fp->f_ops->fo_ioctl;
543 switch (args->cmd & 0xffff) {
544
545 case LINUX_TCGETA:
546 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
547 return error;
548 bsd_to_linux_termio(&bsd_termios, &linux_termio);
549 return copyout((caddr_t)&linux_termio, (caddr_t)args->arg,
550 sizeof(linux_termio));
551
552 case LINUX_TCSETA:
553 error = copyin((caddr_t)args->arg, &linux_termio, sizeof(linux_termio));
554 if (error)
555 return error;
556 linux_to_bsd_termio(&linux_termio, &bsd_termios);
557 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
558
559 case LINUX_TCSETAW:
560 error = copyin((caddr_t)args->arg, &linux_termio, sizeof(linux_termio));
561 if (error)
562 return error;
563 linux_to_bsd_termio(&linux_termio, &bsd_termios);
564 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
565
566 case LINUX_TCSETAF:
567 error = copyin((caddr_t)args->arg, &linux_termio, sizeof(linux_termio));
568 if (error)
569 return error;
570 linux_to_bsd_termio(&linux_termio, &bsd_termios);
571 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
572
573 case LINUX_TCGETS:
574 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
575 return error;
576 bsd_to_linux_termios(&bsd_termios, &linux_termios);
577 return copyout((caddr_t)&linux_termios, (caddr_t)args->arg,
578 sizeof(linux_termios));
579
580 case LINUX_TCSETS:
581 error = copyin((caddr_t)args->arg, &linux_termios,
582 sizeof(linux_termios));
583 if (error)
584 return error;
585 linux_to_bsd_termios(&linux_termios, &bsd_termios);
586 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
587
588 case LINUX_TCSETSW:
589 error = copyin((caddr_t)args->arg, &linux_termios,
590 sizeof(linux_termios));
591 if (error)
592 return error;
593 linux_to_bsd_termios(&linux_termios, &bsd_termios);
594 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
595
596 case LINUX_TCSETSF:
597 error = copyin((caddr_t)args->arg, &linux_termios,
598 sizeof(linux_termios));
599 if (error)
600 return error;
601 linux_to_bsd_termios(&linux_termios, &bsd_termios);
602 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
603
604 case LINUX_TIOCGPGRP:
605 args->cmd = TIOCGPGRP;
606 return ioctl(p, (struct ioctl_args *)args);
607
608 case LINUX_TIOCSPGRP:
609 args->cmd = TIOCSPGRP;
610 return ioctl(p, (struct ioctl_args *)args);
611
612 case LINUX_TIOCGWINSZ:
613 args->cmd = TIOCGWINSZ;
614 return ioctl(p, (struct ioctl_args *)args);
615
616 case LINUX_TIOCSWINSZ:
617 args->cmd = TIOCSWINSZ;
618 return ioctl(p, (struct ioctl_args *)args);
619
620 case LINUX_TIOCMGET:
621 args->cmd = TIOCMGET;
622 return ioctl(p, (struct ioctl_args *)args);
623
624 case LINUX_TIOCMBIS:
625 args->cmd = TIOCMBIS;
626 return ioctl(p, (struct ioctl_args *)args);
627
628 case LINUX_TIOCMBIC:
629 args->cmd = TIOCMBIC;
630 return ioctl(p, (struct ioctl_args *)args);
631
632 case LINUX_TIOCMSET:
633 args->cmd = TIOCMSET;
634 return ioctl(p, (struct ioctl_args *)args);
635
636 case LINUX_FIONREAD:
637 args->cmd = FIONREAD;
638 return ioctl(p, (struct ioctl_args *)args);
639
640 case LINUX_FIONBIO:
641 args->cmd = FIONBIO;
642 return ioctl(p, (struct ioctl_args *)args);
643
644 case LINUX_FIOASYNC:
645 args->cmd = FIOASYNC;
646 return ioctl(p, (struct ioctl_args *)args);
647
648 case LINUX_FIONCLEX:
649 args->cmd = FIONCLEX;
650 return ioctl(p, (struct ioctl_args *)args);
651
652 case LINUX_FIOCLEX:
653 args->cmd = FIOCLEX;
654 return ioctl(p, (struct ioctl_args *)args);
655
656 case LINUX_TIOCEXCL:
657 args->cmd = TIOCEXCL;
658 return ioctl(p, (struct ioctl_args *)args);
659
660 case LINUX_TIOCNXCL:
661 args->cmd = TIOCNXCL;
662 return ioctl(p, (struct ioctl_args *)args);
663
664 case LINUX_TIOCCONS:
665 args->cmd = TIOCCONS;
666 return ioctl(p, (struct ioctl_args *)args);
667
668 case LINUX_TIOCNOTTY:
669 args->cmd = TIOCNOTTY;
670 return ioctl(p, (struct ioctl_args *)args);
671
672 case LINUX_SIOCGIFCONF:
673 args->cmd = OSIOCGIFCONF;
674 return ioctl(p, (struct ioctl_args *)args);
675
676 case LINUX_SIOCGIFFLAGS:
677 args->cmd = SIOCGIFFLAGS;
678 return ioctl(p, (struct ioctl_args *)args);
679
680 case LINUX_SIOCGIFADDR:
681 args->cmd = OSIOCGIFADDR;
682 return ioctl(p, (struct ioctl_args *)args);
683
684 case LINUX_SIOCGIFDSTADDR:
685 args->cmd = OSIOCGIFDSTADDR;
686 return ioctl(p, (struct ioctl_args *)args);
687
688 case LINUX_SIOCGIFBRDADDR:
689 args->cmd = OSIOCGIFBRDADDR;
690 return ioctl(p, (struct ioctl_args *)args);
691
692 case LINUX_SIOCGIFNETMASK:
693 args->cmd = OSIOCGIFNETMASK;
694 return ioctl(p, (struct ioctl_args *)args);
695
696 /* get hardware address */
697 case LINUX_SIOCGIFHWADDR:
698 {
699 int ifn;
700 struct ifnet *ifp;
701 struct ifaddr *ifa;
702 struct sockaddr_dl *sdl;
703 struct linux_ifreq *ifr = (struct linux_ifreq *)args->arg;
704
705 /*
706 * Note that we don't actually respect the name in the ifreq structure, as
707 * Linux interface names are all different
708 */
709
710 for (ifn = 0; ifn < if_index; ifn++) {
711
712 ifp = ifnet_addrs[ifn]->ifa_ifp; /* pointer to interface */
713 if (ifp->if_type == IFT_ETHER) { /* looks good */
714 /* walk the address list */
715 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = TAILQ_NEXT(ifa, ifa_link)) {
716 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && /* we have an address structure */
717 (sdl->sdl_family == AF_LINK) && /* it's a link address */
718 (sdl->sdl_type == IFT_ETHER)) { /* for an ethernet link */
719
720 return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_IFHWADDRLEN));
721 }
722 }
723 }
724 }
725 return(ENOENT); /* ??? */
726 }
727
728 case LINUX_SIOCADDMULTI:
729 args->cmd = SIOCADDMULTI;
730 return ioctl(p, (struct ioctl_args *)args);
731
732 case LINUX_SIOCDELMULTI:
733 args->cmd = SIOCDELMULTI;
734 return ioctl(p, (struct ioctl_args *)args);
735
736 case LINUX_FIOSETOWN:
737 args->cmd = FIOSETOWN;
738 return ioctl(p, (struct ioctl_args *)args);
739
740 case LINUX_SIOCSPGRP:
741 args->cmd = SIOCSPGRP;
742 return ioctl(p, (struct ioctl_args *)args);
743
744 case LINUX_FIOGETOWN:
745 args->cmd = FIOGETOWN;
746 return ioctl(p, (struct ioctl_args *)args);
747
748 case LINUX_SIOCGPGRP:
749 args->cmd = SIOCGPGRP;
750 return ioctl(p, (struct ioctl_args *)args);
751
752 case LINUX_SIOCATMARK:
753 args->cmd = SIOCATMARK;
754 return ioctl(p, (struct ioctl_args *)args);
755
756 case LINUX_TIOCSETD:
757 switch (args->arg) {
758 case LINUX_N_TTY:
759 bsd_line = TTYDISC;
760 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
761 case LINUX_N_SLIP:
762 bsd_line = SLIPDISC;
763 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
764 case LINUX_N_PPP:
765 bsd_line = PPPDISC;
766 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
767 default:
768 return EINVAL;
769 }
770
771 case LINUX_TIOCGETD:
772 bsd_line = TTYDISC;
773 if (error =(*func)(fp, TIOCGETD, (caddr_t)&bsd_line, p))
774 return error;
775 switch (bsd_line) {
776 case TTYDISC:
777 linux_line = LINUX_N_TTY;
778 break;
779 case SLIPDISC:
780 linux_line = LINUX_N_SLIP;
781 break;
782 case PPPDISC:
783 linux_line = LINUX_N_PPP;
784 break;
785 default:
786 return EINVAL;
787 }
788 return copyout(&linux_line, (caddr_t)args->arg,
789 sizeof(int));
790
791 case LINUX_SNDCTL_SEQ_RESET:
792 args->cmd = SNDCTL_SEQ_RESET;
793 return ioctl(p, (struct ioctl_args *)args);
794
795 case LINUX_SNDCTL_SEQ_SYNC:
796 args->cmd = SNDCTL_SEQ_SYNC;
797 return ioctl(p, (struct ioctl_args *)args);
798
799 case LINUX_SNDCTL_SYNTH_INFO:
800 args->cmd = SNDCTL_SYNTH_INFO;
801 return ioctl(p, (struct ioctl_args *)args);
802
803 case LINUX_SNDCTL_SEQ_CTRLRATE:
804 args->cmd = SNDCTL_SEQ_CTRLRATE;
805 return ioctl(p, (struct ioctl_args *)args);
806
807 case LINUX_SNDCTL_SEQ_GETOUTCOUNT:
808 args->cmd = SNDCTL_SEQ_GETOUTCOUNT;
809 return ioctl(p, (struct ioctl_args *)args);
810
811 case LINUX_SNDCTL_SEQ_GETINCOUNT:
812 args->cmd = SNDCTL_SEQ_GETINCOUNT;
813 return ioctl(p, (struct ioctl_args *)args);
814
815 case LINUX_SNDCTL_SEQ_PERCMODE:
816 args->cmd = SNDCTL_SEQ_PERCMODE;
817 return ioctl(p, (struct ioctl_args *)args);
818
819 case LINUX_SNDCTL_FM_LOAD_INSTR:
820 args->cmd = SNDCTL_FM_LOAD_INSTR;
821 return ioctl(p, (struct ioctl_args *)args);
822
823 case LINUX_SNDCTL_SEQ_TESTMIDI:
824 args->cmd = SNDCTL_SEQ_TESTMIDI;
825 return ioctl(p, (struct ioctl_args *)args);
826
827 case LINUX_SNDCTL_SEQ_RESETSAMPLES:
828 args->cmd = SNDCTL_SEQ_RESETSAMPLES;
829 return ioctl(p, (struct ioctl_args *)args);
830
831 case LINUX_SNDCTL_SEQ_NRSYNTHS:
832 args->cmd = SNDCTL_SEQ_NRSYNTHS;
833 return ioctl(p, (struct ioctl_args *)args);
834
835 case LINUX_SNDCTL_SEQ_NRMIDIS:
836 args->cmd = SNDCTL_SEQ_NRMIDIS;
837 return ioctl(p, (struct ioctl_args *)args);
838
839 case LINUX_SNDCTL_MIDI_INFO:
840 args->cmd = SNDCTL_MIDI_INFO;
841 return ioctl(p, (struct ioctl_args *)args);
842
843 case LINUX_SNDCTL_SEQ_TRESHOLD:
844 args->cmd = SNDCTL_SEQ_TRESHOLD;
845 return ioctl(p, (struct ioctl_args *)args);
846
847 case LINUX_SNDCTL_SYNTH_MEMAVL:
848 args->cmd = SNDCTL_SYNTH_MEMAVL;
849 return ioctl(p, (struct ioctl_args *)args);
850
851 case LINUX_SNDCTL_DSP_GETOPTR :
852 args->cmd = SNDCTL_DSP_GETOPTR;
853 return ioctl(p, (struct ioctl_args *)args);
854
855 case LINUX_SNDCTL_DSP_GETIPTR :
856 args->cmd = SNDCTL_DSP_GETIPTR;
857 return ioctl(p, (struct ioctl_args *)args);
858
859 case LINUX_SNDCTL_DSP_SETTRIGGER:
860 args->cmd = SNDCTL_DSP_SETTRIGGER;
861 return ioctl(p, (struct ioctl_args *)args);
862
863 case LINUX_SNDCTL_DSP_GETCAPS:
864 args->cmd = SNDCTL_DSP_GETCAPS;
865 return ioctl(p, (struct ioctl_args *)args);
866
867 case LINUX_SNDCTL_DSP_RESET:
868 args->cmd = SNDCTL_DSP_RESET;
869 return ioctl(p, (struct ioctl_args *)args);
870
871 case LINUX_SNDCTL_DSP_SYNC:
872 args->cmd = SNDCTL_DSP_SYNC;
873 return ioctl(p, (struct ioctl_args *)args);
874
875 case LINUX_SNDCTL_DSP_SPEED:
876 args->cmd = SNDCTL_DSP_SPEED;
877 return ioctl(p, (struct ioctl_args *)args);
878
879 case LINUX_SNDCTL_DSP_STEREO:
880 args->cmd = SNDCTL_DSP_STEREO;
881 return ioctl(p, (struct ioctl_args *)args);
882
883 case LINUX_SNDCTL_DSP_GETBLKSIZE:
884 /* LINUX_SNDCTL_DSP_SETBLKSIZE */
885 args->cmd = SNDCTL_DSP_GETBLKSIZE;
886 return ioctl(p, (struct ioctl_args *)args);
887
888 case LINUX_SNDCTL_DSP_GETODELAY:
889 args->cmd = SNDCTL_DSP_GETODELAY;
890 return ioctl(p, (struct ioctl_args *)args);
891
892 case LINUX_SNDCTL_DSP_SETFMT:
893 args->cmd = SNDCTL_DSP_SETFMT;
894 return ioctl(p, (struct ioctl_args *)args);
895
896 case LINUX_SOUND_PCM_WRITE_CHANNELS:
897 args->cmd = SOUND_PCM_WRITE_CHANNELS;
898 return ioctl(p, (struct ioctl_args *)args);
899
900 case LINUX_SOUND_PCM_WRITE_FILTER:
901 args->cmd = SOUND_PCM_WRITE_FILTER;
902 return ioctl(p, (struct ioctl_args *)args);
903
904 case LINUX_SNDCTL_DSP_POST:
905 args->cmd = SNDCTL_DSP_POST;
906 return ioctl(p, (struct ioctl_args *)args);
907
908 case LINUX_SNDCTL_DSP_SUBDIVIDE:
909 args->cmd = SNDCTL_DSP_SUBDIVIDE;
910 return ioctl(p, (struct ioctl_args *)args);
911
912 case LINUX_SNDCTL_DSP_SETFRAGMENT:
913 args->cmd = SNDCTL_DSP_SETFRAGMENT;
914 return ioctl(p, (struct ioctl_args *)args);
915
916 case LINUX_SNDCTL_DSP_GETFMTS:
917 args->cmd = SNDCTL_DSP_GETFMTS;
918 return ioctl(p, (struct ioctl_args *)args);
919
920 case LINUX_SNDCTL_DSP_GETOSPACE:
921 args->cmd = SNDCTL_DSP_GETOSPACE;
922 return ioctl(p, (struct ioctl_args *)args);
923
924 case LINUX_SNDCTL_DSP_GETISPACE:
925 args->cmd = SNDCTL_DSP_GETISPACE;
926 return ioctl(p, (struct ioctl_args *)args);
927
928 case LINUX_SNDCTL_DSP_NONBLOCK:
929 args->cmd = SNDCTL_DSP_NONBLOCK;
930 return ioctl(p, (struct ioctl_args *)args);
931
932 case LINUX_SOUND_MIXER_WRITE_VOLUME:
933 args->cmd = SETDIR(SOUND_MIXER_WRITE_VOLUME);
934 return ioctl(p, (struct ioctl_args *)args);
935
936 case LINUX_SOUND_MIXER_WRITE_BASS:
937 args->cmd = SETDIR(SOUND_MIXER_WRITE_BASS);
938 return ioctl(p, (struct ioctl_args *)args);
939
940 case LINUX_SOUND_MIXER_WRITE_TREBLE:
941 args->cmd = SETDIR(SOUND_MIXER_WRITE_TREBLE);
942 return ioctl(p, (struct ioctl_args *)args);
943
944 case LINUX_SOUND_MIXER_WRITE_SYNTH:
945 args->cmd = SETDIR(SOUND_MIXER_WRITE_SYNTH);
946 return ioctl(p, (struct ioctl_args *)args);
947
948 case LINUX_SOUND_MIXER_WRITE_PCM:
949 args->cmd = SETDIR(SOUND_MIXER_WRITE_PCM);
950 return ioctl(p, (struct ioctl_args *)args);
951
952 case LINUX_SOUND_MIXER_WRITE_SPEAKER:
953 args->cmd = SETDIR(SOUND_MIXER_WRITE_SPEAKER);
954 return ioctl(p, (struct ioctl_args *)args);
955
956 case LINUX_SOUND_MIXER_WRITE_LINE:
957 args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE);
958 return ioctl(p, (struct ioctl_args *)args);
959
960 case LINUX_SOUND_MIXER_WRITE_MIC:
961 args->cmd = SETDIR(SOUND_MIXER_WRITE_MIC);
962 return ioctl(p, (struct ioctl_args *)args);
963
964 case LINUX_SOUND_MIXER_WRITE_CD:
965 args->cmd = SETDIR(SOUND_MIXER_WRITE_CD);
966 return ioctl(p, (struct ioctl_args *)args);
967
968 case LINUX_SOUND_MIXER_WRITE_IMIX:
969 args->cmd = SETDIR(SOUND_MIXER_WRITE_IMIX);
970 return ioctl(p, (struct ioctl_args *)args);
971
972 case LINUX_SOUND_MIXER_WRITE_ALTPCM:
973 args->cmd = SETDIR(SOUND_MIXER_WRITE_ALTPCM);
974 return ioctl(p, (struct ioctl_args *)args);
975
976 case LINUX_SOUND_MIXER_WRITE_RECLEV:
977 args->cmd = SETDIR(SOUND_MIXER_WRITE_RECLEV);
978 return ioctl(p, (struct ioctl_args *)args);
979
980 case LINUX_SOUND_MIXER_WRITE_IGAIN:
981 args->cmd = SETDIR(SOUND_MIXER_WRITE_IGAIN);
982 return ioctl(p, (struct ioctl_args *)args);
983
984 case LINUX_SOUND_MIXER_WRITE_OGAIN:
985 args->cmd = SETDIR(SOUND_MIXER_WRITE_OGAIN);
986 return ioctl(p, (struct ioctl_args *)args);
987
988 case LINUX_SOUND_MIXER_WRITE_LINE1:
989 args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE1);
990 return ioctl(p, (struct ioctl_args *)args);
991
992 case LINUX_SOUND_MIXER_WRITE_LINE2:
993 args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE2);
994 return ioctl(p, (struct ioctl_args *)args);
995
996 case LINUX_SOUND_MIXER_WRITE_LINE3:
997 args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE3);
998 return ioctl(p, (struct ioctl_args *)args);
999
1000 case LINUX_SOUND_MIXER_READ_DEVMASK:
1001 args->cmd = SOUND_MIXER_READ_DEVMASK;
1002 return ioctl(p, (struct ioctl_args *)args);
1003
1004 case LINUX_TIOCGSERIAL: {
1005 struct linux_serial_struct lss;
1006
1007 lss.type = LINUX_PORT_16550A;
1008 lss.flags = 0;
1009 lss.close_delay = 0;
1010 return copyout((caddr_t)&lss, (caddr_t)args->arg, sizeof(lss));
1011 }
1012
1013 case LINUX_TIOCSSERIAL: {
1014 struct linux_serial_struct lss;
1015
1016 error = copyin((caddr_t)args->arg, (caddr_t)&lss, sizeof(lss));
1017 if (error)
1018 return error;
1019 /*
1020 * XXX - It really helps to have an implementation that does nothing.
1021 * NOT!
1022 */
1023 return 0;
1024 }
1025
1026 case LINUX_TCXONC:
1027 switch (args->arg) {
1028 case LINUX_TCOOFF:
1029 args->cmd = TIOCSTOP;
1030 break;
1031 case LINUX_TCOON:
1032 args->cmd = TIOCSTART;
1033 break;
1034 case LINUX_TCIOFF:
1035 case LINUX_TCION: {
1036 u_char c;
1037 struct write_args wr;
1038 error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p);
1039 if (error != 0)
1040 return error;
1041 c = bsd_termios.c_cc[args->arg == LINUX_TCIOFF ? VSTOP : VSTART];
1042 if (c != _POSIX_VDISABLE) {
1043 wr.fd = args->fd;
1044 wr.buf = &c;
1045 wr.nbyte = sizeof(c);
1046 return write(p, &wr);
1047 }
1048 else
1049 return (0);
1050 }
1051 default:
1052 return EINVAL;
1053 }
1054 args->arg = 0;
1055 return ioctl(p, (struct ioctl_args *)args);
1056
1057 case LINUX_TCFLSH:
1058 args->cmd = TIOCFLUSH;
1059 switch (args->arg) {
1060 case LINUX_TCIFLUSH:
1061 args->arg = FREAD;
1062 break;
1063 case LINUX_TCOFLUSH:
1064 args->arg = FWRITE;
1065 break;
1066 case LINUX_TCIOFLUSH:
1067 args->arg = FREAD | FWRITE;
1068 break;
1069 default:
1070 return EINVAL;
1071 }
1072 return ioctl(p, (struct ioctl_args *)args);
1073
1074 case LINUX_VT_OPENQRY:
1075
1076 args->cmd = VT_OPENQRY;
1077 return ioctl(p, (struct ioctl_args *)args);
1078
1079 case LINUX_VT_GETMODE:
1080
1081 args->cmd = VT_GETMODE;
1082 return ioctl(p, (struct ioctl_args *)args);
1083
1084 case LINUX_VT_RELDISP:
1085
1086 args->cmd = VT_RELDISP;
1087 return ioctl(p, (struct ioctl_args *)args);
1088
1089 case LINUX_VT_SETMODE:
1090 {
1091 struct vt_mode *mode;
1092 args->cmd = VT_SETMODE;
1093 mode = (struct vt_mode *)args->arg;
1094 if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig))
1095 mode->frsig = mode->acqsig;
1096 return ioctl(p, (struct ioctl_args *)args);
1097 }
1098
1099 case LINUX_VT_GETSTATE:
1100
1101 args->cmd = VT_GETACTIVE;
1102 return ioctl(p, (struct ioctl_args *)args);
1103
1104 case LINUX_VT_ACTIVATE:
1105
1106 args->cmd = VT_ACTIVATE;
1107 return ioctl(p, (struct ioctl_args *)args);
1108
1109 case LINUX_VT_WAITACTIVE:
1110
1111 args->cmd = VT_WAITACTIVE;
1112 return ioctl(p, (struct ioctl_args *)args);
1113
1114 case LINUX_KDGKBMODE:
1115
1116 args->cmd = KDGKBMODE;
1117 return ioctl(p, (struct ioctl_args *)args);
1118
1119 case LINUX_KDSKBMODE:
1120 {
1121 int kbdmode;
1122 switch (args->arg) {
1123 case LINUX_KBD_RAW:
1124 kbdmode = K_RAW;
1125 return (*func)(fp, KDSKBMODE, (caddr_t)&kbdmode, p);
1126 case LINUX_KBD_XLATE:
1127 kbdmode = K_XLATE;
1128 return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
1129 case LINUX_KBD_MEDIUMRAW:
1130 kbdmode = K_RAW;
1131 return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
1132 default:
1133 return EINVAL;
1134 }
1135 }
1136
1137 case LINUX_KDGETMODE:
1138 args->cmd = KDGETMODE;
1139 return ioctl(p, (struct ioctl_args *)args);
1140
1141 case LINUX_KDSETMODE:
1142 args->cmd = KDSETMODE;
1143 return ioctl(p, (struct ioctl_args *)args);
1144
1145 case LINUX_KDSETLED:
1146 args->cmd = KDSETLED;
1147 return ioctl(p, (struct ioctl_args *)args);
1148
1149 case LINUX_KDGETLED:
1150 args->cmd = KDGETLED;
1151 return ioctl(p, (struct ioctl_args *)args);
1152
1153 case LINUX_KIOCSOUND:
1154 args->cmd = KIOCSOUND;
1155 return ioctl(p, (struct ioctl_args *)args);
1156
1157 case LINUX_KDMKTONE:
1158 args->cmd = KDMKTONE;
1159 return ioctl(p, (struct ioctl_args *)args);
1160
1161
1162 case LINUX_CDROMPAUSE:
1163 args->cmd = CDIOCPAUSE;
1164 return ioctl(p, (struct ioctl_args *)args);
1165
1166 case LINUX_CDROMRESUME:
1167 args->cmd = CDIOCRESUME;
1168 return ioctl(p, (struct ioctl_args *)args);
1169
1170 case LINUX_CDROMPLAYMSF:
1171 args->cmd = CDIOCPLAYMSF;
1172 return ioctl(p, (struct ioctl_args *)args);
1173
1174 case LINUX_CDROMPLAYTRKIND:
1175 args->cmd = CDIOCPLAYTRACKS;
1176 return ioctl(p, (struct ioctl_args *)args);
1177
1178 case LINUX_CDROMSTART:
1179 args->cmd = CDIOCSTART;
1180 return ioctl(p, (struct ioctl_args *)args);
1181
1182 case LINUX_CDROMSTOP:
1183 args->cmd = CDIOCSTOP;
1184 return ioctl(p, (struct ioctl_args *)args);
1185
1186 case LINUX_CDROMEJECT:
1187 args->cmd = CDIOCEJECT;
1188 return ioctl(p, (struct ioctl_args *)args);
1189
1190 case LINUX_CDROMRESET:
1191 args->cmd = CDIOCRESET;
1192 return ioctl(p, (struct ioctl_args *)args);
1193
1194 case LINUX_CDROMREADTOCHDR: {
1195 struct ioc_toc_header th;
1196 struct linux_cdrom_tochdr lth;
1197 error = (*func)(fp, CDIOREADTOCHEADER, (caddr_t)&th, p);
1198 if (!error) {
1199 lth.cdth_trk0 = th.starting_track;
1200 lth.cdth_trk1 = th.ending_track;
1201 copyout((caddr_t)<h, (caddr_t)args->arg, sizeof(lth));
1202 }
1203 return error;
1204 }
1205
1206 case LINUX_CDROMREADTOCENTRY: {
1207 struct linux_cdrom_tocentry lte, *ltep =
1208 (struct linux_cdrom_tocentry *)args->arg;
1209 struct ioc_read_toc_single_entry irtse;
1210 irtse.address_format = ltep->cdte_format;
1211 irtse.track = ltep->cdte_track;
1212 error = (*func)(fp, CDIOREADTOCENTRY, (caddr_t)&irtse, p);
1213 if (!error) {
1214 lte = *ltep;
1215 lte.cdte_ctrl = irtse.entry.control;
1216 lte.cdte_adr = irtse.entry.addr_type;
1217 bsd_to_linux_msf_lba(irtse.address_format,
1218 &irtse.entry.addr, <e.cdte_addr);
1219 copyout((caddr_t)<e, (caddr_t)args->arg, sizeof(lte));
1220 }
1221 return error;
1222 }
1223
1224 case LINUX_CDROMSUBCHNL: {
1225 caddr_t sg;
1226 struct linux_cdrom_subchnl sc;
1227 struct ioc_read_subchannel bsdsc;
1228 struct cd_sub_channel_info *bsdinfo;
1229
1230 sg = stackgap_init();
1231 bsdinfo = (struct cd_sub_channel_info*)stackgap_alloc(&sg,
1232 sizeof(struct cd_sub_channel_info));
1233
1234 bsdsc.address_format = CD_LBA_FORMAT;
1235 bsdsc.data_format = CD_CURRENT_POSITION;
1236 bsdsc.data_len = sizeof(struct cd_sub_channel_info);
1237 bsdsc.data = bsdinfo;
1238 error = (*func)(fp, CDIOCREADSUBCHANNEL, (caddr_t)&bsdsc, p);
1239 if (error)
1240 return error;
1241
1242 error = copyin((caddr_t)args->arg, (caddr_t)&sc,
1243 sizeof(struct linux_cdrom_subchnl));
1244 if (error)
1245 return error;
1246
1247 sc.cdsc_audiostatus = bsdinfo->header.audio_status;
1248 sc.cdsc_adr = bsdinfo->what.position.addr_type;
1249 sc.cdsc_ctrl = bsdinfo->what.position.control;
1250 sc.cdsc_trk = bsdinfo->what.position.track_number;
1251 sc.cdsc_ind = bsdinfo->what.position.index_number;
1252 set_linux_cdrom_addr(&sc.cdsc_absaddr, sc.cdsc_format,
1253 bsdinfo->what.position.absaddr.lba);
1254 set_linux_cdrom_addr(&sc.cdsc_reladdr, sc.cdsc_format,
1255 bsdinfo->what.position.reladdr.lba);
1256 error = copyout((caddr_t)&sc, (caddr_t)args->arg,
1257 sizeof(struct linux_cdrom_subchnl));
1258 return error;
1259 }
1260
1261 }
1262
1263 uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
1264 args->fd, (u_int)((args->cmd & 0xffff00) >> 8),
1265 (int)((args->cmd & 0xffff00) >> 8), (u_int)(args->cmd & 0xff));
1266 return EINVAL;
1267 }
Cache object: 639e9c5e329f08b87d26f5bf0558a27f
|