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