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