1/* 2 * linux/drivers/char/tty_ioctl.c 3 * 4 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 5 * 6 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines 7 * which can be dynamically activated and de-activated by the line 8 * discipline handling modules (like SLIP). 9 */ 10 11#include <linux/types.h> 12#include <linux/termios.h> 13#include <linux/errno.h> 14#include <linux/sched.h> 15#include <linux/kernel.h> 16#include <linux/major.h> 17#include <linux/tty.h> 18#include <linux/fcntl.h> 19#include <linux/string.h> 20#include <linux/mm.h> 21#include <linux/module.h> 22#include <linux/bitops.h> 23#include <linux/mutex.h> 24 25#include <asm/io.h> 26#include <asm/uaccess.h> 27#include <asm/system.h> 28 29#undef TTY_DEBUG_WAIT_UNTIL_SENT 30 31#undef DEBUG 32 33/* 34 * Internal flag options for termios setting behavior 35 */ 36#define TERMIOS_FLUSH 1 37#define TERMIOS_WAIT 2 38#define TERMIOS_TERMIO 4 39#define TERMIOS_OLD 8 40 41 42/** 43 * tty_wait_until_sent - wait for I/O to finish 44 * @tty: tty we are waiting for 45 * @timeout: how long we will wait 46 * 47 * Wait for characters pending in a tty driver to hit the wire, or 48 * for a timeout to occur (eg due to flow control) 49 * 50 * Locking: none 51 */ 52 53void tty_wait_until_sent(struct tty_struct * tty, long timeout) 54{ 55 DECLARE_WAITQUEUE(wait, current); 56 57#ifdef TTY_DEBUG_WAIT_UNTIL_SENT 58 char buf[64]; 59 60 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); 61#endif 62 if (!tty->driver->chars_in_buffer) 63 return; 64 add_wait_queue(&tty->write_wait, &wait); 65 if (!timeout) 66 timeout = MAX_SCHEDULE_TIMEOUT; 67 do { 68#ifdef TTY_DEBUG_WAIT_UNTIL_SENT 69 printk(KERN_DEBUG "waiting %s...(%d)\n", tty_name(tty, buf), 70 tty->driver->chars_in_buffer(tty)); 71#endif 72 set_current_state(TASK_INTERRUPTIBLE); 73 if (signal_pending(current)) 74 goto stop_waiting; 75 if (!tty->driver->chars_in_buffer(tty)) 76 break; 77 timeout = schedule_timeout(timeout); 78 } while (timeout); 79 if (tty->driver->wait_until_sent) 80 tty->driver->wait_until_sent(tty, timeout); 81stop_waiting: 82 set_current_state(TASK_RUNNING); 83 remove_wait_queue(&tty->write_wait, &wait); 84} 85 86EXPORT_SYMBOL(tty_wait_until_sent); 87 88static void unset_locked_termios(struct ktermios *termios, 89 struct ktermios *old, 90 struct ktermios *locked) 91{ 92 int i; 93 94#define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z))) 95 96 if (!locked) { 97 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n"); 98 return; 99 } 100 101 NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag); 102 NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag); 103 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); 104 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag); 105 termios->c_line = locked->c_line ? old->c_line : termios->c_line; 106 for (i=0; i < NCCS; i++) 107 termios->c_cc[i] = locked->c_cc[i] ? 108 old->c_cc[i] : termios->c_cc[i]; 109} 110 111/* 112 * Routine which returns the baud rate of the tty 113 * 114 * Note that the baud_table needs to be kept in sync with the 115 * include/asm/termbits.h file. 116 */ 117static const speed_t baud_table[] = { 118 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 119 9600, 19200, 38400, 57600, 115200, 230400, 460800, 120#ifdef __sparc__ 121 76800, 153600, 307200, 614400, 921600 122#else 123 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 124 2500000, 3000000, 3500000, 4000000 125#endif 126}; 127 128#ifndef __sparc__ 129static const tcflag_t baud_bits[] = { 130 B0, B50, B75, B110, B134, B150, B200, B300, B600, 131 B1200, B1800, B2400, B4800, B9600, B19200, B38400, 132 B57600, B115200, B230400, B460800, B500000, B576000, 133 B921600, B1000000, B1152000, B1500000, B2000000, B2500000, 134 B3000000, B3500000, B4000000 135}; 136#else 137static const tcflag_t baud_bits[] = { 138 B0, B50, B75, B110, B134, B150, B200, B300, B600, 139 B1200, B1800, B2400, B4800, B9600, B19200, B38400, 140 B57600, B115200, B230400, B460800, B76800, B153600, 141 B307200, B614400, B921600 142}; 143#endif 144 145static int n_baud_table = ARRAY_SIZE(baud_table); 146 147/** 148 * tty_termios_baud_rate 149 * @termios: termios structure 150 * 151 * Convert termios baud rate data into a speed. This should be called 152 * with the termios lock held if this termios is a terminal termios 153 * structure. May change the termios data. Device drivers can call this 154 * function but should use ->c_[io]speed directly as they are updated. 155 * 156 * Locking: none 157 */ 158 159speed_t tty_termios_baud_rate(struct ktermios *termios) 160{ 161 unsigned int cbaud; 162 163 cbaud = termios->c_cflag & CBAUD; 164 165#ifdef BOTHER 166 /* Magic token for arbitary speed via c_ispeed/c_ospeed */ 167 if (cbaud == BOTHER) 168 return termios->c_ospeed; 169#endif 170 if (cbaud & CBAUDEX) { 171 cbaud &= ~CBAUDEX; 172 173 if (cbaud < 1 || cbaud + 15 > n_baud_table) 174 termios->c_cflag &= ~CBAUDEX; 175 else 176 cbaud += 15; 177 } 178 return baud_table[cbaud]; 179} 180 181EXPORT_SYMBOL(tty_termios_baud_rate); 182 183/** 184 * tty_termios_input_baud_rate 185 * @termios: termios structure 186 * 187 * Convert termios baud rate data into a speed. This should be called 188 * with the termios lock held if this termios is a terminal termios 189 * structure. May change the termios data. Device drivers can call this 190 * function but should use ->c_[io]speed directly as they are updated. 191 * 192 * Locking: none 193 */ 194 195speed_t tty_termios_input_baud_rate(struct ktermios *termios) 196{ 197#ifdef IBSHIFT 198 unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD; 199 200 if (cbaud == B0) 201 return tty_termios_baud_rate(termios); 202 203 /* Magic token for arbitary speed via c_ispeed*/ 204 if (cbaud == BOTHER) 205 return termios->c_ispeed; 206 207 if (cbaud & CBAUDEX) { 208 cbaud &= ~CBAUDEX; 209 210 if (cbaud < 1 || cbaud + 15 > n_baud_table) 211 termios->c_cflag &= ~(CBAUDEX << IBSHIFT); 212 else 213 cbaud += 15; 214 } 215 return baud_table[cbaud]; 216#else 217 return tty_termios_baud_rate(termios); 218#endif 219} 220 221EXPORT_SYMBOL(tty_termios_input_baud_rate); 222 223#ifdef BOTHER 224 225/** 226 * tty_termios_encode_baud_rate 227 * @termios: ktermios structure holding user requested state 228 * @ispeed: input speed 229 * @ospeed: output speed 230 * 231 * Encode the speeds set into the passed termios structure. This is 232 * used as a library helper for drivers os that they can report back 233 * the actual speed selected when it differs from the speed requested 234 * 235 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour 236 * we need to carefully set the bits when the user does not get the 237 * desired speed. We allow small margins and preserve as much of possible 238 * of the input intent to keep compatiblity. 239 * 240 * Locking: Caller should hold termios lock. This is already held 241 * when calling this function from the driver termios handler. 242 */ 243 244void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) 245{ 246 int i = 0; 247 int ifound = -1, ofound = -1; 248 int iclose = ibaud/50, oclose = obaud/50; 249 int ibinput = 0; 250 251 termios->c_ispeed = ibaud; 252 termios->c_ospeed = obaud; 253 254 /* If the user asked for a precise weird speed give a precise weird 255 answer. If they asked for a Bfoo speed they many have problems 256 digesting non-exact replies so fuzz a bit */ 257 258 if ((termios->c_cflag & CBAUD) == BOTHER) 259 oclose = 0; 260 if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER) 261 iclose = 0; 262 if ((termios->c_cflag >> IBSHIFT) & CBAUD) 263 ibinput = 1; /* An input speed was specified */ 264 265 termios->c_cflag &= ~CBAUD; 266 267 do { 268 if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) { 269 termios->c_cflag |= baud_bits[i]; 270 ofound = i; 271 } 272 if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) { 273 /* For the case input == output don't set IBAUD bits if the user didn't do so */ 274 if (ofound != i || ibinput) 275 termios->c_cflag |= (baud_bits[i] << IBSHIFT); 276 ifound = i; 277 } 278 } 279 while(++i < n_baud_table); 280 if (ofound == -1) 281 termios->c_cflag |= BOTHER; 282 /* Set exact input bits only if the input and output differ or the 283 user already did */ 284 if (ifound == -1 && (ibaud != obaud || ibinput)) 285 termios->c_cflag |= (BOTHER << IBSHIFT); 286} 287 288EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); 289 290#endif 291 292/** 293 * tty_get_baud_rate - get tty bit rates 294 * @tty: tty to query 295 * 296 * Returns the baud rate as an integer for this terminal. The 297 * termios lock must be held by the caller and the terminal bit 298 * flags may be updated. 299 * 300 * Locking: none 301 */ 302 303speed_t tty_get_baud_rate(struct tty_struct *tty) 304{ 305 speed_t baud = tty_termios_baud_rate(tty->termios); 306 307 if (baud == 38400 && tty->alt_speed) { 308 if (!tty->warned) { 309 printk(KERN_WARNING "Use of setserial/setrocket to " 310 "set SPD_* flags is deprecated\n"); 311 tty->warned = 1; 312 } 313 baud = tty->alt_speed; 314 } 315 316 return baud; 317} 318 319EXPORT_SYMBOL(tty_get_baud_rate); 320 321/** 322 * change_termios - update termios values 323 * @tty: tty to update 324 * @new_termios: desired new value 325 * 326 * Perform updates to the termios values set on this terminal. There 327 * is a bit of layering violation here with n_tty in terms of the 328 * internal knowledge of this function. 329 * 330 * Locking: termios_sem 331 */ 332 333static void change_termios(struct tty_struct * tty, struct ktermios * new_termios) 334{ 335 int canon_change; 336 struct ktermios old_termios = *tty->termios; 337 struct tty_ldisc *ld; 338 339 /* 340 * Perform the actual termios internal changes under lock. 341 */ 342 343 344 mutex_lock(&tty->termios_mutex); 345 346 *tty->termios = *new_termios; 347 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); 348 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; 349 if (canon_change) { 350 memset(&tty->read_flags, 0, sizeof tty->read_flags); 351 tty->canon_head = tty->read_tail; 352 tty->canon_data = 0; 353 tty->erasing = 0; 354 } 355 356 357 if (canon_change && !L_ICANON(tty) && tty->read_cnt) 358 /* Get characters left over from canonical mode. */ 359 wake_up_interruptible(&tty->read_wait); 360 361 /* See if packet mode change of state. */ 362 363 if (tty->link && tty->link->packet) { 364 int old_flow = ((old_termios.c_iflag & IXON) && 365 (old_termios.c_cc[VSTOP] == '\023') && 366 (old_termios.c_cc[VSTART] == '\021')); 367 int new_flow = (I_IXON(tty) && 368 STOP_CHAR(tty) == '\023' && 369 START_CHAR(tty) == '\021'); 370 if (old_flow != new_flow) { 371 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); 372 if (new_flow) 373 tty->ctrl_status |= TIOCPKT_DOSTOP; 374 else 375 tty->ctrl_status |= TIOCPKT_NOSTOP; 376 wake_up_interruptible(&tty->link->read_wait); 377 } 378 } 379 380 if (tty->driver->set_termios) 381 (*tty->driver->set_termios)(tty, &old_termios); 382 383 ld = tty_ldisc_ref(tty); 384 if (ld != NULL) { 385 if (ld->set_termios) 386 (ld->set_termios)(tty, &old_termios); 387 tty_ldisc_deref(ld); 388 } 389 mutex_unlock(&tty->termios_mutex); 390} 391 392/** 393 * set_termios - set termios values for a tty 394 * @tty: terminal device 395 * @arg: user data 396 * @opt: option information 397 * 398 * Helper function to prepare termios data and run neccessary other 399 * functions before using change_termios to do the actual changes. 400 * 401 * Locking: 402 * Called functions take ldisc and termios_sem locks 403 */ 404 405static int set_termios(struct tty_struct * tty, void __user *arg, int opt) 406{ 407 struct ktermios tmp_termios; 408 struct tty_ldisc *ld; 409 int retval = tty_check_change(tty); 410 411 if (retval) 412 return retval; 413 414 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); 415 416 if (opt & TERMIOS_TERMIO) { 417 if (user_termio_to_kernel_termios(&tmp_termios, 418 (struct termio __user *)arg)) 419 return -EFAULT; 420#ifdef TCGETS2 421 } else if (opt & TERMIOS_OLD) { 422 if (user_termios_to_kernel_termios_1(&tmp_termios, 423 (struct termios __user *)arg)) 424 return -EFAULT; 425 } else { 426 if (user_termios_to_kernel_termios(&tmp_termios, 427 (struct termios2 __user *)arg)) 428 return -EFAULT; 429 } 430#else 431 } else if (user_termios_to_kernel_termios(&tmp_termios, 432 (struct termios __user *)arg)) 433 return -EFAULT; 434#endif 435 436 /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed 437 so its unconditionally usable */ 438 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); 439 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); 440 441 ld = tty_ldisc_ref(tty); 442 443 if (ld != NULL) { 444 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) 445 ld->flush_buffer(tty); 446 tty_ldisc_deref(ld); 447 } 448 449 if (opt & TERMIOS_WAIT) { 450 tty_wait_until_sent(tty, 0); 451 if (signal_pending(current)) 452 return -EINTR; 453 } 454 455 change_termios(tty, &tmp_termios); 456 return 0; 457} 458 459static int get_termio(struct tty_struct * tty, struct termio __user * termio) 460{ 461 if (kernel_termios_to_user_termio(termio, tty->termios)) 462 return -EFAULT; 463 return 0; 464} 465 466static unsigned long inq_canon(struct tty_struct * tty) 467{ 468 int nr, head, tail; 469 470 if (!tty->canon_data || !tty->read_buf) 471 return 0; 472 head = tty->canon_head; 473 tail = tty->read_tail; 474 nr = (head - tail) & (N_TTY_BUF_SIZE-1); 475 /* Skip EOF-chars.. */ 476 while (head != tail) { 477 if (test_bit(tail, tty->read_flags) && 478 tty->read_buf[tail] == __DISABLED_CHAR) 479 nr--; 480 tail = (tail+1) & (N_TTY_BUF_SIZE-1); 481 } 482 return nr; 483} 484 485#ifdef TIOCGETP 486/* 487 * These are deprecated, but there is limited support.. 488 * 489 * The "sg_flags" translation is a joke.. 490 */ 491static int get_sgflags(struct tty_struct * tty) 492{ 493 int flags = 0; 494 495 if (!(tty->termios->c_lflag & ICANON)) { 496 if (tty->termios->c_lflag & ISIG) 497 flags |= 0x02; /* cbreak */ 498 else 499 flags |= 0x20; /* raw */ 500 } 501 if (tty->termios->c_lflag & ECHO) 502 flags |= 0x08; /* echo */ 503 if (tty->termios->c_oflag & OPOST) 504 if (tty->termios->c_oflag & ONLCR) 505 flags |= 0x10; /* crmod */ 506 return flags; 507} 508 509static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) 510{ 511 struct sgttyb tmp; 512 513 mutex_lock(&tty->termios_mutex); 514 tmp.sg_ispeed = tty->termios->c_ispeed; 515 tmp.sg_ospeed = tty->termios->c_ospeed; 516 tmp.sg_erase = tty->termios->c_cc[VERASE]; 517 tmp.sg_kill = tty->termios->c_cc[VKILL]; 518 tmp.sg_flags = get_sgflags(tty); 519 mutex_unlock(&tty->termios_mutex); 520 521 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; 522} 523 524static void set_sgflags(struct ktermios * termios, int flags) 525{ 526 termios->c_iflag = ICRNL | IXON; 527 termios->c_oflag = 0; 528 termios->c_lflag = ISIG | ICANON; 529 if (flags & 0x02) { /* cbreak */ 530 termios->c_iflag = 0; 531 termios->c_lflag &= ~ICANON; 532 } 533 if (flags & 0x08) { /* echo */ 534 termios->c_lflag |= ECHO | ECHOE | ECHOK | 535 ECHOCTL | ECHOKE | IEXTEN; 536 } 537 if (flags & 0x10) { /* crmod */ 538 termios->c_oflag |= OPOST | ONLCR; 539 } 540 if (flags & 0x20) { /* raw */ 541 termios->c_iflag = 0; 542 termios->c_lflag &= ~(ISIG | ICANON); 543 } 544 if (!(termios->c_lflag & ICANON)) { 545 termios->c_cc[VMIN] = 1; 546 termios->c_cc[VTIME] = 0; 547 } 548} 549 550/** 551 * set_sgttyb - set legacy terminal values 552 * @tty: tty structure 553 * @sgttyb: pointer to old style terminal structure 554 * 555 * Updates a terminal from the legacy BSD style terminal information 556 * structure. 557 * 558 * Locking: termios_sem 559 */ 560 561static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) 562{ 563 int retval; 564 struct sgttyb tmp; 565 struct ktermios termios; 566 567 retval = tty_check_change(tty); 568 if (retval) 569 return retval; 570 571 if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) 572 return -EFAULT; 573 574 mutex_lock(&tty->termios_mutex); 575 termios = *tty->termios; 576 termios.c_cc[VERASE] = tmp.sg_erase; 577 termios.c_cc[VKILL] = tmp.sg_kill; 578 set_sgflags(&termios, tmp.sg_flags); 579 /* Try and encode into Bfoo format */ 580#ifdef BOTHER 581 tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed); 582#endif 583 mutex_unlock(&tty->termios_mutex); 584 change_termios(tty, &termios); 585 return 0; 586} 587#endif 588 589#ifdef TIOCGETC 590static int get_tchars(struct tty_struct * tty, struct tchars __user * tchars) 591{ 592 struct tchars tmp; 593 594 tmp.t_intrc = tty->termios->c_cc[VINTR]; 595 tmp.t_quitc = tty->termios->c_cc[VQUIT]; 596 tmp.t_startc = tty->termios->c_cc[VSTART]; 597 tmp.t_stopc = tty->termios->c_cc[VSTOP]; 598 tmp.t_eofc = tty->termios->c_cc[VEOF]; 599 tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ 600 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 601} 602 603static int set_tchars(struct tty_struct * tty, struct tchars __user * tchars) 604{ 605 struct tchars tmp; 606 607 if (copy_from_user(&tmp, tchars, sizeof(tmp))) 608 return -EFAULT; 609 tty->termios->c_cc[VINTR] = tmp.t_intrc; 610 tty->termios->c_cc[VQUIT] = tmp.t_quitc; 611 tty->termios->c_cc[VSTART] = tmp.t_startc; 612 tty->termios->c_cc[VSTOP] = tmp.t_stopc; 613 tty->termios->c_cc[VEOF] = tmp.t_eofc; 614 tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ 615 return 0; 616} 617#endif 618 619#ifdef TIOCGLTC 620static int get_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) 621{ 622 struct ltchars tmp; 623 624 tmp.t_suspc = tty->termios->c_cc[VSUSP]; 625 tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; /* what is dsuspc anyway? */ 626 tmp.t_rprntc = tty->termios->c_cc[VREPRINT]; 627 tmp.t_flushc = tty->termios->c_cc[VEOL2]; /* what is flushc anyway? */ 628 tmp.t_werasc = tty->termios->c_cc[VWERASE]; 629 tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; 630 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 631} 632 633static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) 634{ 635 struct ltchars tmp; 636 637 if (copy_from_user(&tmp, ltchars, sizeof(tmp))) 638 return -EFAULT; 639 640 tty->termios->c_cc[VSUSP] = tmp.t_suspc; 641 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; /* what is dsuspc anyway? */ 642 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc; 643 tty->termios->c_cc[VEOL2] = tmp.t_flushc; /* what is flushc anyway? */ 644 tty->termios->c_cc[VWERASE] = tmp.t_werasc; 645 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; 646 return 0; 647} 648#endif 649 650/** 651 * send_prio_char - send priority character 652 * 653 * Send a high priority character to the tty even if stopped 654 * 655 * Locking: none for xchar method, write ordering for write method. 656 */ 657 658static int send_prio_char(struct tty_struct *tty, char ch) 659{ 660 int was_stopped = tty->stopped; 661 662 if (tty->driver->send_xchar) { 663 tty->driver->send_xchar(tty, ch); 664 return 0; 665 } 666 667 if (mutex_lock_interruptible(&tty->atomic_write_lock)) 668 return -ERESTARTSYS; 669 670 if (was_stopped) 671 start_tty(tty); 672 tty->driver->write(tty, &ch, 1); 673 if (was_stopped) 674 stop_tty(tty); 675 mutex_unlock(&tty->atomic_write_lock); 676 return 0; 677} 678 679int n_tty_ioctl(struct tty_struct * tty, struct file * file, 680 unsigned int cmd, unsigned long arg) 681{ 682 struct tty_struct * real_tty; 683 void __user *p = (void __user *)arg; 684 int retval; 685 struct tty_ldisc *ld; 686 687 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 688 tty->driver->subtype == PTY_TYPE_MASTER) 689 real_tty = tty->link; 690 else 691 real_tty = tty; 692 693 switch (cmd) { 694#ifdef TIOCGETP 695 case TIOCGETP: 696 return get_sgttyb(real_tty, (struct sgttyb __user *) arg); 697 case TIOCSETP: 698 case TIOCSETN: 699 return set_sgttyb(real_tty, (struct sgttyb __user *) arg); 700#endif 701#ifdef TIOCGETC 702 case TIOCGETC: 703 return get_tchars(real_tty, p); 704 case TIOCSETC: 705 return set_tchars(real_tty, p); 706#endif 707#ifdef TIOCGLTC 708 case TIOCGLTC: 709 return get_ltchars(real_tty, p); 710 case TIOCSLTC: 711 return set_ltchars(real_tty, p); 712#endif 713 case TCSETSF: 714 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); 715 case TCSETSW: 716 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); 717 case TCSETS: 718 return set_termios(real_tty, p, TERMIOS_OLD); 719#ifndef TCGETS2 720 case TCGETS: 721 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) 722 return -EFAULT; 723 return 0; 724#else 725 case TCGETS: 726 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) 727 return -EFAULT; 728 return 0; 729 case TCGETS2: 730 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) 731 return -EFAULT; 732 return 0; 733 case TCSETSF2: 734 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); 735 case TCSETSW2: 736 return set_termios(real_tty, p, TERMIOS_WAIT); 737 case TCSETS2: 738 return set_termios(real_tty, p, 0); 739#endif 740 case TCGETA: 741 return get_termio(real_tty, p); 742 case TCSETAF: 743 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO); 744 case TCSETAW: 745 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO); 746 case TCSETA: 747 return set_termios(real_tty, p, TERMIOS_TERMIO); 748 case TCXONC: 749 retval = tty_check_change(tty); 750 if (retval) 751 return retval; 752 switch (arg) { 753 case TCOOFF: 754 if (!tty->flow_stopped) { 755 tty->flow_stopped = 1; 756 stop_tty(tty); 757 } 758 break; 759 case TCOON: 760 if (tty->flow_stopped) { 761 tty->flow_stopped = 0; 762 start_tty(tty); 763 } 764 break; 765 case TCIOFF: 766 if (STOP_CHAR(tty) != __DISABLED_CHAR) 767 return send_prio_char(tty, STOP_CHAR(tty)); 768 break; 769 case TCION: 770 if (START_CHAR(tty) != __DISABLED_CHAR) 771 return send_prio_char(tty, START_CHAR(tty)); 772 break; 773 default: 774 return -EINVAL; 775 } 776 return 0; 777 case TCFLSH: 778 retval = tty_check_change(tty); 779 if (retval) 780 return retval; 781 782 ld = tty_ldisc_ref(tty); 783 switch (arg) { 784 case TCIFLUSH: 785 if (ld && ld->flush_buffer) 786 ld->flush_buffer(tty); 787 break; 788 case TCIOFLUSH: 789 if (ld && ld->flush_buffer) 790 ld->flush_buffer(tty); 791 /* fall through */ 792 case TCOFLUSH: 793 if (tty->driver->flush_buffer) 794 tty->driver->flush_buffer(tty); 795 break; 796 default: 797 tty_ldisc_deref(ld); 798 return -EINVAL; 799 } 800 tty_ldisc_deref(ld); 801 return 0; 802 case TIOCOUTQ: 803 return put_user(tty->driver->chars_in_buffer ? 804 tty->driver->chars_in_buffer(tty) : 0, 805 (int __user *) arg); 806 case TIOCINQ: 807 retval = tty->read_cnt; 808 if (L_ICANON(tty)) 809 retval = inq_canon(tty); 810 return put_user(retval, (unsigned int __user *) arg); 811 case TIOCGLCKTRMIOS: 812 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) 813 return -EFAULT; 814 return 0; 815 816 case TIOCSLCKTRMIOS: 817 if (!capable(CAP_SYS_ADMIN)) 818 return -EPERM; 819 if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) 820 return -EFAULT; 821 return 0; 822 823 case TIOCPKT: 824 { 825 int pktmode; 826 827 if (tty->driver->type != TTY_DRIVER_TYPE_PTY || 828 tty->driver->subtype != PTY_TYPE_MASTER) 829 return -ENOTTY; 830 if (get_user(pktmode, (int __user *) arg)) 831 return -EFAULT; 832 if (pktmode) { 833 if (!tty->packet) { 834 tty->packet = 1; 835 tty->link->ctrl_status = 0; 836 } 837 } else 838 tty->packet = 0; 839 return 0; 840 } 841 case TIOCGSOFTCAR: 842 return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg); 843 case TIOCSSOFTCAR: 844 if (get_user(arg, (unsigned int __user *) arg)) 845 return -EFAULT; 846 mutex_lock(&tty->termios_mutex); 847 tty->termios->c_cflag = 848 ((tty->termios->c_cflag & ~CLOCAL) | 849 (arg ? CLOCAL : 0)); 850 mutex_unlock(&tty->termios_mutex); 851 return 0; 852 default: 853 return -ENOIOCTLCMD; 854 } 855} 856 857EXPORT_SYMBOL(n_tty_ioctl); 858