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.10 1996/06/12 05:06:27 gpalmer 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 <sys/sockio.h> 45 46 #include <machine/soundcard.h> 47 48 #include <i386/linux/linux.h> 49 #include <i386/linux/linux_proto.h> 50 51 struct linux_termio { 52 unsigned short c_iflag; 53 unsigned short c_oflag; 54 unsigned short c_cflag; 55 unsigned short c_lflag; 56 unsigned char c_line; 57 unsigned char c_cc[LINUX_NCC]; 58 }; 59 60 61 struct linux_termios { 62 unsigned long c_iflag; 63 unsigned long c_oflag; 64 unsigned long c_cflag; 65 unsigned long c_lflag; 66 unsigned char c_line; 67 unsigned char c_cc[LINUX_NCCS]; 68 }; 69 70 struct linux_winsize { 71 unsigned short ws_row, ws_col; 72 unsigned short ws_xpixel, ws_ypixel; 73 }; 74 75 static struct speedtab sptab[] = { 76 { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 }, 77 { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 }, 78 { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 }, 79 { 2400, 11 }, { 4800, 12 }, { 9600, 13 }, 80 { 19200, 14 }, { 38400, 15 }, 81 { 57600, 4097 }, { 115200, 4098 }, {-1, -1 } 82 }; 83 84 struct linux_serial_struct { 85 int type; 86 int line; 87 int port; 88 int irq; 89 int flags; 90 int xmit_fifo_size; 91 int custom_divisor; 92 int baud_base; 93 unsigned short close_delay; 94 char reserved_char[2]; 95 int hub6; 96 unsigned short closing_wait; 97 unsigned short closing_wait2; 98 int reserved[4]; 99 }; 100 101 102 static int 103 linux_to_bsd_speed(int code, struct speedtab *table) 104 { 105 for ( ; table->sp_code != -1; table++) 106 if (table->sp_code == code) 107 return (table->sp_speed); 108 return -1; 109 } 110 111 static int 112 bsd_to_linux_speed(int speed, struct speedtab *table) 113 { 114 for ( ; table->sp_speed != -1; table++) 115 if (table->sp_speed == speed) 116 return (table->sp_code); 117 return -1; 118 } 119 120 static void 121 bsd_to_linux_termios(struct termios *bsd_termios, 122 struct linux_termios *linux_termios) 123 { 124 int i; 125 126 #ifdef DEBUG 127 printf("LINUX: BSD termios structure (input):\n"); 128 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", 129 bsd_termios->c_iflag, bsd_termios->c_oflag, 130 bsd_termios->c_cflag, bsd_termios->c_lflag, 131 bsd_termios->c_ispeed, bsd_termios->c_ospeed); 132 printf("c_cc "); 133 for (i=0; i<NCCS; i++) 134 printf("%02x ", bsd_termios->c_cc[i]); 135 printf("\n"); 136 #endif 137 linux_termios->c_iflag = 0; 138 if (bsd_termios->c_iflag & IGNBRK) 139 linux_termios->c_iflag |= LINUX_IGNBRK; 140 if (bsd_termios->c_iflag & BRKINT) 141 linux_termios->c_iflag |= LINUX_BRKINT; 142 if (bsd_termios->c_iflag & IGNPAR) 143 linux_termios->c_iflag |= LINUX_IGNPAR; 144 if (bsd_termios->c_iflag & PARMRK) 145 linux_termios->c_iflag |= LINUX_PARMRK; 146 if (bsd_termios->c_iflag & INPCK) 147 linux_termios->c_iflag |= LINUX_INPCK; 148 if (bsd_termios->c_iflag & ISTRIP) 149 linux_termios->c_iflag |= LINUX_ISTRIP; 150 if (bsd_termios->c_iflag & INLCR) 151 linux_termios->c_iflag |= LINUX_INLCR; 152 if (bsd_termios->c_iflag & IGNCR) 153 linux_termios->c_iflag |= LINUX_IGNCR; 154 if (bsd_termios->c_iflag & ICRNL) 155 linux_termios->c_iflag |= LINUX_ICRNL; 156 if (bsd_termios->c_iflag & IXON) 157 linux_termios->c_iflag |= LINUX_IXANY; 158 if (bsd_termios->c_iflag & IXON) 159 linux_termios->c_iflag |= LINUX_IXON; 160 if (bsd_termios->c_iflag & IXOFF) 161 linux_termios->c_iflag |= LINUX_IXOFF; 162 if (bsd_termios->c_iflag & IMAXBEL) 163 linux_termios->c_iflag |= LINUX_IMAXBEL; 164 165 linux_termios->c_oflag = 0; 166 if (bsd_termios->c_oflag & OPOST) 167 linux_termios->c_oflag |= LINUX_OPOST; 168 if (bsd_termios->c_oflag & ONLCR) 169 linux_termios->c_oflag |= LINUX_ONLCR; 170 if (bsd_termios->c_oflag & OXTABS) 171 linux_termios->c_oflag |= LINUX_XTABS; 172 173 linux_termios->c_cflag = 174 bsd_to_linux_speed(bsd_termios->c_ispeed, sptab); 175 linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4; 176 if (bsd_termios->c_cflag & CSTOPB) 177 linux_termios->c_cflag |= LINUX_CSTOPB; 178 if (bsd_termios->c_cflag & CREAD) 179 linux_termios->c_cflag |= LINUX_CREAD; 180 if (bsd_termios->c_cflag & PARENB) 181 linux_termios->c_cflag |= LINUX_PARENB; 182 if (bsd_termios->c_cflag & PARODD) 183 linux_termios->c_cflag |= LINUX_PARODD; 184 if (bsd_termios->c_cflag & HUPCL) 185 linux_termios->c_cflag |= LINUX_HUPCL; 186 if (bsd_termios->c_cflag & CLOCAL) 187 linux_termios->c_cflag |= LINUX_CLOCAL; 188 if (bsd_termios->c_cflag & CRTSCTS) 189 linux_termios->c_cflag |= LINUX_CRTSCTS; 190 191 linux_termios->c_lflag = 0; 192 if (bsd_termios->c_lflag & ISIG) 193 linux_termios->c_lflag |= LINUX_ISIG; 194 if (bsd_termios->c_lflag & ICANON) 195 linux_termios->c_lflag |= LINUX_ICANON; 196 if (bsd_termios->c_lflag & ECHO) 197 linux_termios->c_lflag |= LINUX_ECHO; 198 if (bsd_termios->c_lflag & ECHOE) 199 linux_termios->c_lflag |= LINUX_ECHOE; 200 if (bsd_termios->c_lflag & ECHOK) 201 linux_termios->c_lflag |= LINUX_ECHOK; 202 if (bsd_termios->c_lflag & ECHONL) 203 linux_termios->c_lflag |= LINUX_ECHONL; 204 if (bsd_termios->c_lflag & NOFLSH) 205 linux_termios->c_lflag |= LINUX_NOFLSH; 206 if (bsd_termios->c_lflag & TOSTOP) 207 linux_termios->c_lflag |= LINUX_TOSTOP; 208 if (bsd_termios->c_lflag & ECHOCTL) 209 linux_termios->c_lflag |= LINUX_ECHOCTL; 210 if (bsd_termios->c_lflag & ECHOPRT) 211 linux_termios->c_lflag |= LINUX_ECHOPRT; 212 if (bsd_termios->c_lflag & ECHOKE) 213 linux_termios->c_lflag |= LINUX_ECHOKE; 214 if (bsd_termios->c_lflag & FLUSHO) 215 linux_termios->c_lflag |= LINUX_FLUSHO; 216 if (bsd_termios->c_lflag & PENDIN) 217 linux_termios->c_lflag |= LINUX_PENDIN; 218 if (bsd_termios->c_lflag & IEXTEN) 219 linux_termios->c_lflag |= LINUX_IEXTEN; 220 221 for (i=0; i<LINUX_NCCS; i++) 222 linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE; 223 linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR]; 224 linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT]; 225 linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE]; 226 linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL]; 227 linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF]; 228 linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL]; 229 linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN]; 230 linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME]; 231 linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2]; 232 linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE; 233 linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP]; 234 linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART]; 235 linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP]; 236 linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT]; 237 linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD]; 238 linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE]; 239 linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT]; 240 241 for (i=0; i<LINUX_NCCS; i++) { 242 if (linux_termios->c_cc[i] == _POSIX_VDISABLE) 243 linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE; 244 } 245 246 linux_termios->c_line = 0; 247 #ifdef DEBUG 248 printf("LINUX: LINUX termios structure (output):\n"); 249 printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", 250 linux_termios->c_iflag, linux_termios->c_oflag, 251 linux_termios->c_cflag, linux_termios->c_lflag, 252 linux_termios->c_line); 253 printf("c_cc "); 254 for (i=0; i<LINUX_NCCS; i++) 255 printf("%02x ", linux_termios->c_cc[i]); 256 printf("\n"); 257 #endif 258 } 259 260 261 static void 262 linux_to_bsd_termios(struct linux_termios *linux_termios, 263 struct termios *bsd_termios) 264 { 265 int i; 266 #ifdef DEBUG 267 printf("LINUX: LINUX termios structure (input):\n"); 268 printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", 269 linux_termios->c_iflag, linux_termios->c_oflag, 270 linux_termios->c_cflag, linux_termios->c_lflag, 271 linux_termios->c_line); 272 printf("c_cc "); 273 for (i=0; i<LINUX_NCCS; i++) 274 printf("%02x ", linux_termios->c_cc[i]); 275 printf("\n"); 276 #endif 277 bsd_termios->c_iflag = 0; 278 if (linux_termios->c_iflag & LINUX_IGNBRK) 279 bsd_termios->c_iflag |= IGNBRK; 280 if (linux_termios->c_iflag & LINUX_BRKINT) 281 bsd_termios->c_iflag |= BRKINT; 282 if (linux_termios->c_iflag & LINUX_IGNPAR) 283 bsd_termios->c_iflag |= IGNPAR; 284 if (linux_termios->c_iflag & LINUX_PARMRK) 285 bsd_termios->c_iflag |= PARMRK; 286 if (linux_termios->c_iflag & LINUX_INPCK) 287 bsd_termios->c_iflag |= INPCK; 288 if (linux_termios->c_iflag & LINUX_ISTRIP) 289 bsd_termios->c_iflag |= ISTRIP; 290 if (linux_termios->c_iflag & LINUX_INLCR) 291 bsd_termios->c_iflag |= INLCR; 292 if (linux_termios->c_iflag & LINUX_IGNCR) 293 bsd_termios->c_iflag |= IGNCR; 294 if (linux_termios->c_iflag & LINUX_ICRNL) 295 bsd_termios->c_iflag |= ICRNL; 296 if (linux_termios->c_iflag & LINUX_IXON) 297 bsd_termios->c_iflag |= IXANY; 298 if (linux_termios->c_iflag & LINUX_IXON) 299 bsd_termios->c_iflag |= IXON; 300 if (linux_termios->c_iflag & LINUX_IXOFF) 301 bsd_termios->c_iflag |= IXOFF; 302 if (linux_termios->c_iflag & LINUX_IMAXBEL) 303 bsd_termios->c_iflag |= IMAXBEL; 304 305 bsd_termios->c_oflag = 0; 306 if (linux_termios->c_oflag & LINUX_OPOST) 307 bsd_termios->c_oflag |= OPOST; 308 if (linux_termios->c_oflag & LINUX_ONLCR) 309 bsd_termios->c_oflag |= ONLCR; 310 if (linux_termios->c_oflag & LINUX_XTABS) 311 bsd_termios->c_oflag |= OXTABS; 312 313 bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4; 314 if (linux_termios->c_cflag & LINUX_CSTOPB) 315 bsd_termios->c_cflag |= CSTOPB; 316 if (linux_termios->c_cflag & LINUX_PARENB) 317 bsd_termios->c_cflag |= PARENB; 318 if (linux_termios->c_cflag & LINUX_PARODD) 319 bsd_termios->c_cflag |= PARODD; 320 if (linux_termios->c_cflag & LINUX_HUPCL) 321 bsd_termios->c_cflag |= HUPCL; 322 if (linux_termios->c_cflag & LINUX_CLOCAL) 323 bsd_termios->c_cflag |= CLOCAL; 324 if (linux_termios->c_cflag & LINUX_CRTSCTS) 325 bsd_termios->c_cflag |= CRTSCTS; 326 327 bsd_termios->c_lflag = 0; 328 if (linux_termios->c_lflag & LINUX_ISIG) 329 bsd_termios->c_lflag |= ISIG; 330 if (linux_termios->c_lflag & LINUX_ICANON) 331 bsd_termios->c_lflag |= ICANON; 332 if (linux_termios->c_lflag & LINUX_ECHO) 333 bsd_termios->c_lflag |= ECHO; 334 if (linux_termios->c_lflag & LINUX_ECHOE) 335 bsd_termios->c_lflag |= ECHOE; 336 if (linux_termios->c_lflag & LINUX_ECHOK) 337 bsd_termios->c_lflag |= ECHOK; 338 if (linux_termios->c_lflag & LINUX_ECHONL) 339 bsd_termios->c_lflag |= ECHONL; 340 if (linux_termios->c_lflag & LINUX_NOFLSH) 341 bsd_termios->c_lflag |= NOFLSH; 342 if (linux_termios->c_lflag & LINUX_TOSTOP) 343 bsd_termios->c_lflag |= TOSTOP; 344 if (linux_termios->c_lflag & LINUX_ECHOCTL) 345 bsd_termios->c_lflag |= ECHOCTL; 346 if (linux_termios->c_lflag & LINUX_ECHOPRT) 347 bsd_termios->c_lflag |= ECHOPRT; 348 if (linux_termios->c_lflag & LINUX_ECHOKE) 349 bsd_termios->c_lflag |= ECHOKE; 350 if (linux_termios->c_lflag & LINUX_FLUSHO) 351 bsd_termios->c_lflag |= FLUSHO; 352 if (linux_termios->c_lflag & LINUX_PENDIN) 353 bsd_termios->c_lflag |= PENDIN; 354 if (linux_termios->c_lflag & IEXTEN) 355 bsd_termios->c_lflag |= IEXTEN; 356 357 for (i=0; i<NCCS; i++) 358 bsd_termios->c_cc[i] = _POSIX_VDISABLE; 359 bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR]; 360 bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT]; 361 bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE]; 362 bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL]; 363 bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF]; 364 bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL]; 365 bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN]; 366 bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME]; 367 bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2]; 368 bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP]; 369 bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART]; 370 bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP]; 371 bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT]; 372 bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD]; 373 bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE]; 374 bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT]; 375 376 for (i=0; i<NCCS; i++) { 377 if (bsd_termios->c_cc[i] == LINUX_POSIX_VDISABLE) 378 bsd_termios->c_cc[i] = _POSIX_VDISABLE; 379 } 380 381 bsd_termios->c_ispeed = bsd_termios->c_ospeed = 382 linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); 383 #ifdef DEBUG 384 printf("LINUX: BSD termios structure (output):\n"); 385 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", 386 bsd_termios->c_iflag, bsd_termios->c_oflag, 387 bsd_termios->c_cflag, bsd_termios->c_lflag, 388 bsd_termios->c_ispeed, bsd_termios->c_ospeed); 389 printf("c_cc "); 390 for (i=0; i<NCCS; i++) 391 printf("%02x ", bsd_termios->c_cc[i]); 392 printf("\n"); 393 #endif 394 } 395 396 397 static void 398 bsd_to_linux_termio(struct termios *bsd_termios, 399 struct linux_termio *linux_termio) 400 { 401 struct linux_termios tmios; 402 403 bsd_to_linux_termios(bsd_termios, &tmios); 404 linux_termio->c_iflag = tmios.c_iflag; 405 linux_termio->c_oflag = tmios.c_oflag; 406 linux_termio->c_cflag = tmios.c_cflag; 407 linux_termio->c_lflag = tmios.c_lflag; 408 linux_termio->c_line = tmios.c_line; 409 memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC); 410 } 411 412 static void 413 linux_to_bsd_termio(struct linux_termio *linux_termio, 414 struct termios *bsd_termios) 415 { 416 struct linux_termios tmios; 417 int i; 418 419 tmios.c_iflag = linux_termio->c_iflag; 420 tmios.c_oflag = linux_termio->c_oflag; 421 tmios.c_cflag = linux_termio->c_cflag; 422 tmios.c_lflag = linux_termio->c_lflag; 423 424 for (i=0; i<LINUX_NCCS; i++) 425 tmios.c_cc[i] = LINUX_POSIX_VDISABLE; 426 memcpy(tmios.c_cc, linux_termio->c_cc, LINUX_NCC); 427 428 linux_to_bsd_termios(&tmios, bsd_termios); 429 } 430 431 static void 432 linux_tiocgserial(struct file *fp, struct linux_serial_struct *lss) 433 { 434 if (!fp || !lss) 435 return; 436 437 lss->type = LINUX_PORT_16550A; 438 lss->flags = 0; 439 lss->close_delay = 0; 440 } 441 442 static void 443 linux_tiocsserial(struct file *fp, struct linux_serial_struct *lss) 444 { 445 if (!fp || !lss) 446 return; 447 } 448 449 int 450 linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) 451 { 452 struct termios bsd_termios; 453 struct linux_termios linux_termios; 454 struct linux_termio linux_termio; 455 struct filedesc *fdp = p->p_fd; 456 struct file *fp; 457 int (*func)(struct file *fp, int com, caddr_t data, struct proc *p); 458 int bsd_line, linux_line; 459 int error; 460 461 #ifdef DEBUG 462 printf("Linux-emul(%d): ioctl(%d, %04x, *)\n", 463 p->p_pid, args->fd, args->cmd); 464 #endif 465 if ((unsigned)args->fd >= fdp->fd_nfiles 466 || (fp = fdp->fd_ofiles[args->fd]) == 0) 467 return EBADF; 468 469 if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) { 470 return EBADF; 471 } 472 473 func = fp->f_ops->fo_ioctl; 474 switch (args->cmd & 0xffff) { 475 476 case LINUX_TCGETA: 477 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) 478 return error; 479 bsd_to_linux_termio(&bsd_termios, &linux_termio); 480 return copyout((caddr_t)&linux_termio, (caddr_t)args->arg, 481 sizeof(linux_termio)); 482 483 case LINUX_TCSETA: 484 linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); 485 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); 486 487 case LINUX_TCSETAW: 488 linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); 489 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); 490 491 case LINUX_TCSETAF: 492 linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); 493 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); 494 495 case LINUX_TCGETS: 496 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) 497 return error; 498 bsd_to_linux_termios(&bsd_termios, &linux_termios); 499 return copyout((caddr_t)&linux_termios, (caddr_t)args->arg, 500 sizeof(linux_termios)); 501 502 case LINUX_TCSETS: 503 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); 504 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); 505 506 case LINUX_TCSETSW: 507 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); 508 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); 509 510 case LINUX_TCSETSF: 511 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); 512 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); 513 514 case LINUX_TIOCGPGRP: 515 args->cmd = TIOCGPGRP; 516 return ioctl(p, (struct ioctl_args *)args, retval); 517 518 case LINUX_TIOCSPGRP: 519 args->cmd = TIOCSPGRP; 520 return ioctl(p, (struct ioctl_args *)args, retval); 521 522 case LINUX_TIOCGWINSZ: 523 args->cmd = TIOCGWINSZ; 524 return ioctl(p, (struct ioctl_args *)args, retval); 525 526 case LINUX_TIOCSWINSZ: 527 args->cmd = TIOCSWINSZ; 528 return ioctl(p, (struct ioctl_args *)args, retval); 529 530 case LINUX_FIONREAD: 531 args->cmd = FIONREAD; 532 return ioctl(p, (struct ioctl_args *)args, retval); 533 534 case LINUX_FIONBIO: 535 args->cmd = FIONBIO; 536 return ioctl(p, (struct ioctl_args *)args, retval); 537 538 case LINUX_FIOASYNC: 539 args->cmd = FIOASYNC; 540 return ioctl(p, (struct ioctl_args *)args, retval); 541 542 case LINUX_FIONCLEX: 543 args->cmd = FIONCLEX; 544 return ioctl(p, (struct ioctl_args *)args, retval); 545 546 case LINUX_FIOCLEX: 547 args->cmd = FIOCLEX; 548 return ioctl(p, (struct ioctl_args *)args, retval); 549 550 case LINUX_TIOCEXCL: 551 args->cmd = TIOCEXCL; 552 return ioctl(p, (struct ioctl_args *)args, retval); 553 554 case LINUX_TIOCNXCL: 555 args->cmd = TIOCNXCL; 556 return ioctl(p, (struct ioctl_args *)args, retval); 557 558 case LINUX_TIOCCONS: 559 args->cmd = TIOCCONS; 560 return ioctl(p, (struct ioctl_args *)args, retval); 561 562 case LINUX_TIOCNOTTY: 563 args->cmd = TIOCNOTTY; 564 return ioctl(p, (struct ioctl_args *)args, retval); 565 566 case LINUX_SIOCGIFCONF: 567 args->cmd = OSIOCGIFCONF; 568 return ioctl(p, (struct ioctl_args *)args, retval); 569 570 case LINUX_SIOCGIFFLAGS: 571 args->cmd = SIOCGIFFLAGS; 572 return ioctl(p, (struct ioctl_args *)args, retval); 573 574 case LINUX_SIOCGIFADDR: 575 args->cmd = OSIOCGIFADDR; 576 return ioctl(p, (struct ioctl_args *)args, retval); 577 578 case LINUX_SIOCGIFDSTADDR: 579 args->cmd = OSIOCGIFDSTADDR; 580 return ioctl(p, (struct ioctl_args *)args, retval); 581 582 case LINUX_SIOCGIFBRDADDR: 583 args->cmd = OSIOCGIFBRDADDR; 584 return ioctl(p, (struct ioctl_args *)args, retval); 585 586 case LINUX_SIOCGIFNETMASK: 587 args->cmd = OSIOCGIFNETMASK; 588 return ioctl(p, (struct ioctl_args *)args, retval); 589 590 case LINUX_SIOCADDMULTI: 591 args->cmd = SIOCADDMULTI; 592 return ioctl(p, (struct ioctl_args *)args, retval); 593 594 case LINUX_SIOCDELMULTI: 595 args->cmd = SIOCDELMULTI; 596 return ioctl(p, (struct ioctl_args *)args, retval); 597 598 case LINUX_TIOCSETD: 599 switch (args->arg) { 600 case LINUX_N_TTY: 601 bsd_line = TTYDISC; 602 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); 603 case LINUX_N_SLIP: 604 bsd_line = SLIPDISC; 605 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); 606 case LINUX_N_PPP: 607 bsd_line = PPPDISC; 608 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); 609 default: 610 return EINVAL; 611 } 612 613 case LINUX_TIOCGETD: 614 bsd_line = TTYDISC; 615 if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p)) 616 return error; 617 switch (bsd_line) { 618 case TTYDISC: 619 linux_line = LINUX_N_TTY; 620 break; 621 case SLIPDISC: 622 linux_line = LINUX_N_SLIP; 623 break; 624 case PPPDISC: 625 linux_line = LINUX_N_PPP; 626 break; 627 default: 628 return EINVAL; 629 } 630 return copyout(&linux_line, (caddr_t)args->arg, 631 sizeof(int)); 632 633 case LINUX_SNDCTL_DSP_RESET: 634 args->cmd = SNDCTL_DSP_RESET; 635 return ioctl(p, (struct ioctl_args *)args, retval); 636 637 case LINUX_SNDCTL_DSP_SYNC: 638 args->cmd = SNDCTL_DSP_SYNC; 639 return ioctl(p, (struct ioctl_args *)args, retval); 640 641 case LINUX_SNDCTL_DSP_SPEED: 642 args->cmd = SNDCTL_DSP_SPEED; 643 return ioctl(p, (struct ioctl_args *)args, retval); 644 645 case LINUX_SNDCTL_DSP_STEREO: 646 args->cmd = SNDCTL_DSP_STEREO; 647 return ioctl(p, (struct ioctl_args *)args, retval); 648 649 case LINUX_SNDCTL_DSP_GETBLKSIZE: 650 /* LINUX_SNDCTL_DSP_SETBLKSIZE */ 651 args->cmd = SNDCTL_DSP_GETBLKSIZE; 652 return ioctl(p, (struct ioctl_args *)args, retval); 653 654 case LINUX_SNDCTL_DSP_SETFMT: 655 args->cmd = SNDCTL_DSP_SETFMT; 656 return ioctl(p, (struct ioctl_args *)args, retval); 657 658 case LINUX_SOUND_PCM_WRITE_CHANNELS: 659 args->cmd = SOUND_PCM_WRITE_CHANNELS; 660 return ioctl(p, (struct ioctl_args *)args, retval); 661 662 case LINUX_SOUND_PCM_WRITE_FILTER: 663 args->cmd = SOUND_PCM_WRITE_FILTER; 664 return ioctl(p, (struct ioctl_args *)args, retval); 665 666 case LINUX_SNDCTL_DSP_POST: 667 args->cmd = SNDCTL_DSP_POST; 668 return ioctl(p, (struct ioctl_args *)args, retval); 669 670 case LINUX_SNDCTL_DSP_SUBDIVIDE: 671 args->cmd = SNDCTL_DSP_SUBDIVIDE; 672 return ioctl(p, (struct ioctl_args *)args, retval); 673 674 case LINUX_SNDCTL_DSP_SETFRAGMENT: 675 args->cmd = SNDCTL_DSP_SETFRAGMENT; 676 return ioctl(p, (struct ioctl_args *)args, retval); 677 678 case LINUX_SNDCTL_DSP_GETFMTS: 679 args->cmd = SNDCTL_DSP_GETFMTS; 680 return ioctl(p, (struct ioctl_args *)args, retval); 681 682 case LINUX_SNDCTL_DSP_GETOSPACE: 683 args->cmd = SNDCTL_DSP_GETOSPACE; 684 return ioctl(p, (struct ioctl_args *)args, retval); 685 686 case LINUX_SNDCTL_DSP_GETISPACE: 687 args->cmd = SNDCTL_DSP_GETISPACE; 688 return ioctl(p, (struct ioctl_args *)args, retval); 689 690 case LINUX_SNDCTL_DSP_NONBLOCK: 691 args->cmd = SNDCTL_DSP_NONBLOCK; 692 return ioctl(p, (struct ioctl_args *)args, retval); 693 694 case LINUX_TIOCGSERIAL: 695 linux_tiocgserial(fp, (struct linux_serial_struct *)args->arg); 696 return 0; 697 698 case LINUX_TIOCSSERIAL: 699 linux_tiocsserial(fp, (struct linux_serial_struct *)args->arg); 700 return 0; 701 702 case LINUX_TCFLSH: 703 args->cmd = TIOCFLUSH; 704 switch (args->arg) { 705 case LINUX_TCIFLUSH: 706 args->arg = FREAD; 707 break; 708 case LINUX_TCOFLUSH: 709 args->arg = FWRITE; 710 break; 711 case LINUX_TCIOFLUSH: 712 args->arg = FREAD | FWRITE; 713 break; 714 default: 715 return EINVAL; 716 } 717 return ioctl(p, (struct ioctl_args *)args, retval); 718 719 } 720 uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n", 721 args->fd, (args->cmd&0xffff00)>>8, 722 (args->cmd&0xffff00)>>8, args->cmd&0xff); 723 return EINVAL; 724 } 725