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.1 1995/06/25 17:32:35 sos 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 42 #include <machine/console.h> 43 44 #include <i386/linux/linux.h> 45 #include <i386/linux/sysproto.h> 46 47 struct linux_termios { 48 unsigned long c_iflag; 49 unsigned long c_oflag; 50 unsigned long c_cflag; 51 unsigned long c_lflag; 52 unsigned char c_line; 53 unsigned char c_cc[LINUX_NCCS]; 54 }; 55 56 struct linux_winsize { 57 unsigned short ws_row, ws_col; 58 unsigned short ws_xpixel, ws_ypixel; 59 }; 60 61 static struct speedtab sptab[] = { 62 { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 }, 63 { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 }, 64 { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 }, 65 { 2400, 11 }, { 4800, 12 }, { 9600, 13 }, 66 { 19200, 14 }, { 38400, 15 }, 67 { 57600, 4097 }, { 115200, 4098 }, {-1, -1 } 68 }; 69 70 static int 71 linux_to_bsd_speed(int code, struct speedtab *table) 72 { 73 for ( ; table->sp_code != -1; table++) 74 if (table->sp_code == code) 75 return (table->sp_speed); 76 return -1; 77 } 78 79 static int 80 bsd_to_linux_speed(int speed, struct speedtab *table) 81 { 82 for ( ; table->sp_speed != -1; table++) 83 if (table->sp_speed == speed) 84 return (table->sp_code); 85 return -1; 86 } 87 88 static void 89 bsd_to_linux_termios(struct termios *bsd_termios, 90 struct linux_termios *linux_termios) 91 { 92 int i, speed; 93 94 #ifdef DEBUG 95 printf("LINUX: BSD termios structure (input):\n"); 96 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", 97 bsd_termios->c_iflag, bsd_termios->c_oflag, 98 bsd_termios->c_cflag, bsd_termios->c_lflag, 99 bsd_termios->c_ispeed, bsd_termios->c_ospeed); 100 printf("c_cc "); 101 for (i=0; i<NCCS; i++) 102 printf("%02x ", bsd_termios->c_cc[i]); 103 printf("\n"); 104 #endif 105 linux_termios->c_iflag = 0; 106 if (bsd_termios->c_iflag & IGNBRK) 107 linux_termios->c_iflag |= LINUX_IGNBRK; 108 if (bsd_termios->c_iflag & BRKINT) 109 linux_termios->c_iflag |= LINUX_BRKINT; 110 if (bsd_termios->c_iflag & IGNPAR) 111 linux_termios->c_iflag |= LINUX_IGNPAR; 112 if (bsd_termios->c_iflag & PARMRK) 113 linux_termios->c_iflag |= LINUX_PARMRK; 114 if (bsd_termios->c_iflag & INPCK) 115 linux_termios->c_iflag |= LINUX_INPCK; 116 if (bsd_termios->c_iflag & ISTRIP) 117 linux_termios->c_iflag |= LINUX_ISTRIP; 118 if (bsd_termios->c_iflag & INLCR) 119 linux_termios->c_iflag |= LINUX_INLCR; 120 if (bsd_termios->c_iflag & IGNCR) 121 linux_termios->c_iflag |= LINUX_IGNCR; 122 if (bsd_termios->c_iflag & ICRNL) 123 linux_termios->c_iflag |= LINUX_ICRNL; 124 if (bsd_termios->c_iflag & IXON) 125 linux_termios->c_iflag |= LINUX_IXANY; 126 if (bsd_termios->c_iflag & IXON) 127 linux_termios->c_iflag |= LINUX_IXON; 128 if (bsd_termios->c_iflag & IXOFF) 129 linux_termios->c_iflag |= LINUX_IXOFF; 130 if (bsd_termios->c_iflag & IMAXBEL) 131 linux_termios->c_iflag |= LINUX_IMAXBEL; 132 133 linux_termios->c_oflag = 0; 134 if (bsd_termios->c_oflag & OPOST) 135 linux_termios->c_oflag |= LINUX_OPOST; 136 if (bsd_termios->c_oflag & ONLCR) 137 linux_termios->c_oflag |= LINUX_ONLCR; 138 if (bsd_termios->c_oflag & OXTABS) 139 linux_termios->c_oflag |= LINUX_XTABS; 140 141 linux_termios->c_cflag = 142 bsd_to_linux_speed(bsd_termios->c_ispeed, sptab); 143 linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4; 144 if (bsd_termios->c_cflag & CSTOPB) 145 linux_termios->c_cflag |= LINUX_CSTOPB; 146 if (bsd_termios->c_cflag & CREAD) 147 linux_termios->c_cflag |= LINUX_CREAD; 148 if (bsd_termios->c_cflag & PARENB) 149 linux_termios->c_cflag |= LINUX_PARENB; 150 if (bsd_termios->c_cflag & PARODD) 151 linux_termios->c_cflag |= LINUX_PARODD; 152 if (bsd_termios->c_cflag & HUPCL) 153 linux_termios->c_cflag |= LINUX_HUPCL; 154 if (bsd_termios->c_cflag & CLOCAL) 155 linux_termios->c_cflag |= LINUX_CLOCAL; 156 if (bsd_termios->c_cflag & CRTSCTS) 157 linux_termios->c_cflag |= LINUX_CRTSCTS; 158 159 linux_termios->c_lflag = 0; 160 if (bsd_termios->c_lflag & ISIG) 161 linux_termios->c_lflag |= LINUX_ISIG; 162 if (bsd_termios->c_lflag & ICANON) 163 linux_termios->c_lflag |= LINUX_ICANON; 164 if (bsd_termios->c_lflag & ECHO) 165 linux_termios->c_lflag |= LINUX_ECHO; 166 if (bsd_termios->c_lflag & ECHOE) 167 linux_termios->c_lflag |= LINUX_ECHOE; 168 if (bsd_termios->c_lflag & ECHOK) 169 linux_termios->c_lflag |= LINUX_ECHOK; 170 if (bsd_termios->c_lflag & ECHONL) 171 linux_termios->c_lflag |= LINUX_ECHONL; 172 if (bsd_termios->c_lflag & NOFLSH) 173 linux_termios->c_lflag |= LINUX_NOFLSH; 174 if (bsd_termios->c_lflag & TOSTOP) 175 linux_termios->c_lflag |= LINUX_TOSTOP; 176 if (bsd_termios->c_lflag & ECHOCTL) 177 linux_termios->c_lflag |= LINUX_ECHOCTL; 178 if (bsd_termios->c_lflag & ECHOPRT) 179 linux_termios->c_lflag |= LINUX_ECHOPRT; 180 if (bsd_termios->c_lflag & ECHOKE) 181 linux_termios->c_lflag |= LINUX_ECHOKE; 182 if (bsd_termios->c_lflag & FLUSHO) 183 linux_termios->c_lflag |= LINUX_FLUSHO; 184 if (bsd_termios->c_lflag & PENDIN) 185 linux_termios->c_lflag |= LINUX_PENDIN; 186 if (bsd_termios->c_lflag & IEXTEN) 187 linux_termios->c_lflag |= LINUX_IEXTEN; 188 189 for (i=0; i<LINUX_NCCS; i++) 190 linux_termios->c_cc[i] = _POSIX_VDISABLE; 191 linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR]; 192 linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT]; 193 linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE]; 194 linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL]; 195 linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF]; 196 linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL]; 197 linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN]; 198 linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME]; 199 linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2]; 200 linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE; 201 linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP]; 202 linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART]; 203 linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP]; 204 linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT]; 205 linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD]; 206 linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE]; 207 linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT]; 208 209 linux_termios->c_line = 0; 210 #ifdef DEBUG 211 printf("LINUX: LINUX termios structure (output):\n"); 212 printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", 213 linux_termios->c_iflag, linux_termios->c_oflag, 214 linux_termios->c_cflag, linux_termios->c_lflag, 215 linux_termios->c_line); 216 printf("c_cc "); 217 for (i=0; i<LINUX_NCCS; i++) 218 printf("%02x ", linux_termios->c_cc[i]); 219 printf("\n"); 220 #endif 221 } 222 223 static void 224 linux_to_bsd_termios(struct linux_termios *linux_termios, 225 struct termios *bsd_termios) 226 { 227 int i, speed; 228 #ifdef DEBUG 229 printf("LINUX: LINUX termios structure (input):\n"); 230 printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", 231 linux_termios->c_iflag, linux_termios->c_oflag, 232 linux_termios->c_cflag, linux_termios->c_lflag, 233 linux_termios->c_line); 234 printf("c_cc "); 235 for (i=0; i<LINUX_NCCS; i++) 236 printf("%02x ", linux_termios->c_cc[i]); 237 printf("\n"); 238 #endif 239 bsd_termios->c_iflag = 0; 240 if (linux_termios->c_iflag & LINUX_IGNBRK) 241 bsd_termios->c_iflag |= IGNBRK; 242 if (linux_termios->c_iflag & LINUX_BRKINT) 243 bsd_termios->c_iflag |= BRKINT; 244 if (linux_termios->c_iflag & LINUX_IGNPAR) 245 bsd_termios->c_iflag |= IGNPAR; 246 if (linux_termios->c_iflag & LINUX_PARMRK) 247 bsd_termios->c_iflag |= PARMRK; 248 if (linux_termios->c_iflag & LINUX_INPCK) 249 bsd_termios->c_iflag |= INPCK; 250 if (linux_termios->c_iflag & LINUX_ISTRIP) 251 bsd_termios->c_iflag |= ISTRIP; 252 if (linux_termios->c_iflag & LINUX_INLCR) 253 bsd_termios->c_iflag |= INLCR; 254 if (linux_termios->c_iflag & LINUX_IGNCR) 255 bsd_termios->c_iflag |= IGNCR; 256 if (linux_termios->c_iflag & LINUX_ICRNL) 257 bsd_termios->c_iflag |= ICRNL; 258 if (linux_termios->c_iflag & LINUX_IXON) 259 bsd_termios->c_iflag |= IXANY; 260 if (linux_termios->c_iflag & LINUX_IXON) 261 bsd_termios->c_iflag |= IXON; 262 if (linux_termios->c_iflag & LINUX_IXOFF) 263 bsd_termios->c_iflag |= IXOFF; 264 if (linux_termios->c_iflag & LINUX_IMAXBEL) 265 bsd_termios->c_iflag |= IMAXBEL; 266 267 bsd_termios->c_oflag = 0; 268 if (linux_termios->c_oflag & LINUX_OPOST) 269 bsd_termios->c_oflag |= OPOST; 270 if (linux_termios->c_oflag & LINUX_ONLCR) 271 bsd_termios->c_oflag |= ONLCR; 272 if (linux_termios->c_oflag & LINUX_XTABS) 273 bsd_termios->c_oflag |= OXTABS; 274 275 bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4; 276 if (linux_termios->c_cflag & LINUX_CSTOPB) 277 bsd_termios->c_cflag |= CSTOPB; 278 if (linux_termios->c_cflag & LINUX_PARENB) 279 bsd_termios->c_cflag |= PARENB; 280 if (linux_termios->c_cflag & LINUX_PARODD) 281 bsd_termios->c_cflag |= PARODD; 282 if (linux_termios->c_cflag & LINUX_HUPCL) 283 bsd_termios->c_cflag |= HUPCL; 284 if (linux_termios->c_cflag & LINUX_CLOCAL) 285 bsd_termios->c_cflag |= CLOCAL; 286 if (linux_termios->c_cflag & LINUX_CRTSCTS) 287 bsd_termios->c_cflag |= CRTSCTS; 288 289 bsd_termios->c_lflag = 0; 290 if (linux_termios->c_lflag & LINUX_ISIG) 291 bsd_termios->c_lflag |= ISIG; 292 if (linux_termios->c_lflag & LINUX_ICANON) 293 bsd_termios->c_lflag |= ICANON; 294 if (linux_termios->c_lflag & LINUX_ECHO) 295 bsd_termios->c_lflag |= ECHO; 296 if (linux_termios->c_lflag & LINUX_ECHOE) 297 bsd_termios->c_lflag |= ECHOE; 298 if (linux_termios->c_lflag & LINUX_ECHOK) 299 bsd_termios->c_lflag |= ECHOK; 300 if (linux_termios->c_lflag & LINUX_ECHONL) 301 bsd_termios->c_lflag |= ECHONL; 302 if (linux_termios->c_lflag & LINUX_NOFLSH) 303 bsd_termios->c_lflag |= NOFLSH; 304 if (linux_termios->c_lflag & LINUX_TOSTOP) 305 bsd_termios->c_lflag |= TOSTOP; 306 if (linux_termios->c_lflag & LINUX_ECHOCTL) 307 bsd_termios->c_lflag |= ECHOCTL; 308 if (linux_termios->c_lflag & LINUX_ECHOPRT) 309 bsd_termios->c_lflag |= ECHOPRT; 310 if (linux_termios->c_lflag & LINUX_ECHOKE) 311 bsd_termios->c_lflag |= ECHOKE; 312 if (linux_termios->c_lflag & LINUX_FLUSHO) 313 bsd_termios->c_lflag |= FLUSHO; 314 if (linux_termios->c_lflag & LINUX_PENDIN) 315 bsd_termios->c_lflag |= PENDIN; 316 if (linux_termios->c_lflag & IEXTEN) 317 bsd_termios->c_lflag |= IEXTEN; 318 319 for (i=0; i<NCCS; i++) 320 bsd_termios->c_cc[i] = _POSIX_VDISABLE; 321 bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR]; 322 bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT]; 323 bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE]; 324 bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL]; 325 bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF]; 326 bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL]; 327 bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN]; 328 bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME]; 329 bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2]; 330 bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP]; 331 bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART]; 332 bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP]; 333 bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT]; 334 bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD]; 335 bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE]; 336 bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT]; 337 338 bsd_termios->c_ispeed = bsd_termios->c_ospeed = 339 linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); 340 #ifdef DEBUG 341 printf("LINUX: BSD termios structure (output):\n"); 342 printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", 343 bsd_termios->c_iflag, bsd_termios->c_oflag, 344 bsd_termios->c_cflag, bsd_termios->c_lflag, 345 bsd_termios->c_ispeed, bsd_termios->c_ospeed); 346 printf("c_cc "); 347 for (i=0; i<NCCS; i++) 348 printf("%02x ", bsd_termios->c_cc[i]); 349 printf("\n"); 350 #endif 351 } 352 353 354 struct linux_ioctl_args { 355 int fd; 356 int cmd; 357 int arg; 358 }; 359 360 int 361 linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) 362 { 363 struct termios bsd_termios; 364 struct winsize bsd_winsize; 365 struct linux_termios linux_termios; 366 struct linux_winsize linux_winsize; 367 struct filedesc *fdp = p->p_fd; 368 struct file *fp; 369 int (*func)(struct file *fp, int com, caddr_t data, struct proc *p); 370 int bsd_line, linux_line; 371 int error; 372 373 #ifdef DEBUG 374 printf("Linux-emul(%d): ioctl(%d, %04x, *)\n", 375 p->p_pid, args->fd, args->cmd); 376 #endif 377 if ((unsigned)args->fd >= fdp->fd_nfiles 378 || (fp = fdp->fd_ofiles[args->fd]) == 0) 379 return EBADF; 380 381 if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) { 382 return EBADF; 383 } 384 385 func = fp->f_ops->fo_ioctl; 386 switch (args->cmd) { 387 case LINUX_TCGETS: 388 if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) 389 return error; 390 bsd_to_linux_termios(&bsd_termios, &linux_termios); 391 return copyout((caddr_t)&linux_termios, (caddr_t)args->arg, 392 sizeof(linux_termios)); 393 394 case LINUX_TCSETS: 395 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); 396 return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); 397 398 case LINUX_TCSETSW: 399 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); 400 return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); 401 402 case LINUX_TCSETSF: 403 linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); 404 return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); 405 406 case LINUX_TIOCGPGRP: 407 args->cmd = TIOCGPGRP; 408 return ioctl(p, args, retval); 409 410 case LINUX_TIOCSPGRP: 411 args->cmd = TIOCSPGRP; 412 return ioctl(p, args, retval); 413 414 case LINUX_TIOCGWINSZ: 415 args->cmd = TIOCGWINSZ; 416 return ioctl(p, args, retval); 417 418 case LINUX_TIOCSWINSZ: 419 args->cmd = TIOCSWINSZ; 420 return ioctl(p, args, retval); 421 422 case LINUX_FIONREAD: 423 args->cmd = FIONREAD; 424 return ioctl(p, args, retval); 425 426 case LINUX_FIONBIO: 427 args->cmd = FIONBIO; 428 return ioctl(p, args, retval); 429 430 case LINUX_FIOASYNC: 431 args->cmd = FIOASYNC; 432 return ioctl(p, args, retval); 433 434 case LINUX_FIONCLEX: 435 args->cmd = FIONCLEX; 436 return ioctl(p, args, retval); 437 438 case LINUX_FIOCLEX: 439 args->cmd = FIOCLEX; 440 return ioctl(p, args, retval); 441 442 case LINUX_TIOCEXCL: 443 args->cmd = TIOCEXCL; 444 return ioctl(p, args, retval); 445 446 case LINUX_TIOCNXCL: 447 args->cmd = TIOCNXCL; 448 return ioctl(p, args, retval); 449 450 case LINUX_TIOCCONS: 451 args->cmd = TIOCCONS; 452 return ioctl(p, args, retval); 453 454 case LINUX_TIOCNOTTY: 455 args->cmd = TIOCNOTTY; 456 return ioctl(p, args, retval); 457 458 case LINUX_TIOCSETD: 459 switch (args->arg) { 460 case LINUX_N_TTY: 461 bsd_line = TTYDISC; 462 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); 463 case LINUX_N_SLIP: 464 bsd_line = SLIPDISC; 465 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); 466 case LINUX_N_PPP: 467 bsd_line = PPPDISC; 468 return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); 469 default: 470 return EINVAL; 471 } 472 break; 473 474 case LINUX_TIOCGETD: 475 bsd_line = TTYDISC; 476 if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p)) 477 return error; 478 switch (bsd_line) { 479 case TTYDISC: 480 linux_line = LINUX_N_TTY; 481 break; 482 case SLIPDISC: 483 linux_line = LINUX_N_SLIP; 484 break; 485 case PPPDISC: 486 linux_line = LINUX_N_PPP; 487 break; 488 default: 489 return EINVAL; 490 } 491 return copyout(&linux_line, (caddr_t)args->arg, 492 sizeof(int)); 493 } 494 uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n", 495 args->fd, (args->cmd&0xffff00)>>8, 496 (args->cmd&0xffff00)>>8, args->cmd&0xff); 497 return EINVAL; 498 } 499