linux/drivers/char/tty_ioctl.c
<<
>>
Prefs
   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_chars_in_buffer     -       characters pending
  44 *      @tty: terminal
  45 *
  46 *      Return the number of bytes of data in the device private
  47 *      output queue. If no private method is supplied there is assumed
  48 *      to be no queue on the device.
  49 */
  50
  51int tty_chars_in_buffer(struct tty_struct *tty)
  52{
  53        if (tty->ops->chars_in_buffer)
  54                return tty->ops->chars_in_buffer(tty);
  55        else
  56                return 0;
  57}
  58EXPORT_SYMBOL(tty_chars_in_buffer);
  59
  60/**
  61 *      tty_write_room          -       write queue space
  62 *      @tty: terminal
  63 *
  64 *      Return the number of bytes that can be queued to this device
  65 *      at the present time. The result should be treated as a guarantee
  66 *      and the driver cannot offer a value it later shrinks by more than
  67 *      the number of bytes written. If no method is provided 2K is always
  68 *      returned and data may be lost as there will be no flow control.
  69 */
  70 
  71int tty_write_room(struct tty_struct *tty)
  72{
  73        if (tty->ops->write_room)
  74                return tty->ops->write_room(tty);
  75        return 2048;
  76}
  77EXPORT_SYMBOL(tty_write_room);
  78
  79/**
  80 *      tty_driver_flush_buffer -       discard internal buffer
  81 *      @tty: terminal
  82 *
  83 *      Discard the internal output buffer for this device. If no method
  84 *      is provided then either the buffer cannot be hardware flushed or
  85 *      there is no buffer driver side.
  86 */
  87void tty_driver_flush_buffer(struct tty_struct *tty)
  88{
  89        if (tty->ops->flush_buffer)
  90                tty->ops->flush_buffer(tty);
  91}
  92EXPORT_SYMBOL(tty_driver_flush_buffer);
  93
  94/**
  95 *      tty_throttle            -       flow control
  96 *      @tty: terminal
  97 *
  98 *      Indicate that a tty should stop transmitting data down the stack.
  99 *      Takes the termios mutex to protect against parallel throttle/unthrottle
 100 *      and also to ensure the driver can consistently reference its own
 101 *      termios data at this point when implementing software flow control.
 102 */
 103
 104void tty_throttle(struct tty_struct *tty)
 105{
 106        mutex_lock(&tty->termios_mutex);
 107        /* check TTY_THROTTLED first so it indicates our state */
 108        if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
 109            tty->ops->throttle)
 110                tty->ops->throttle(tty);
 111        mutex_unlock(&tty->termios_mutex);
 112}
 113EXPORT_SYMBOL(tty_throttle);
 114
 115/**
 116 *      tty_unthrottle          -       flow control
 117 *      @tty: terminal
 118 *
 119 *      Indicate that a tty may continue transmitting data down the stack.
 120 *      Takes the termios mutex to protect against parallel throttle/unthrottle
 121 *      and also to ensure the driver can consistently reference its own
 122 *      termios data at this point when implementing software flow control.
 123 *
 124 *      Drivers should however remember that the stack can issue a throttle,
 125 *      then change flow control method, then unthrottle.
 126 */
 127
 128void tty_unthrottle(struct tty_struct *tty)
 129{
 130        mutex_lock(&tty->termios_mutex);
 131        if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
 132            tty->ops->unthrottle)
 133                tty->ops->unthrottle(tty);
 134        mutex_unlock(&tty->termios_mutex);
 135}
 136EXPORT_SYMBOL(tty_unthrottle);
 137
 138/**
 139 *      tty_wait_until_sent     -       wait for I/O to finish
 140 *      @tty: tty we are waiting for
 141 *      @timeout: how long we will wait
 142 *
 143 *      Wait for characters pending in a tty driver to hit the wire, or
 144 *      for a timeout to occur (eg due to flow control)
 145 *
 146 *      Locking: none
 147 */
 148
 149void tty_wait_until_sent(struct tty_struct *tty, long timeout)
 150{
 151#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
 152        char buf[64];
 153
 154        printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
 155#endif
 156        if (!timeout)
 157                timeout = MAX_SCHEDULE_TIMEOUT;
 158        if (wait_event_interruptible_timeout(tty->write_wait,
 159                        !tty_chars_in_buffer(tty), timeout) >= 0) {
 160                if (tty->ops->wait_until_sent)
 161                        tty->ops->wait_until_sent(tty, timeout);
 162        }
 163}
 164EXPORT_SYMBOL(tty_wait_until_sent);
 165
 166
 167/*
 168 *              Termios Helper Methods
 169 */
 170
 171static void unset_locked_termios(struct ktermios *termios,
 172                                 struct ktermios *old,
 173                                 struct ktermios *locked)
 174{
 175        int     i;
 176
 177#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
 178
 179        if (!locked) {
 180                printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
 181                return;
 182        }
 183
 184        NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
 185        NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
 186        NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
 187        NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
 188        termios->c_line = locked->c_line ? old->c_line : termios->c_line;
 189        for (i = 0; i < NCCS; i++)
 190                termios->c_cc[i] = locked->c_cc[i] ?
 191                        old->c_cc[i] : termios->c_cc[i];
 192        /* FIXME: What should we do for i/ospeed */
 193}
 194
 195/*
 196 * Routine which returns the baud rate of the tty
 197 *
 198 * Note that the baud_table needs to be kept in sync with the
 199 * include/asm/termbits.h file.
 200 */
 201static const speed_t baud_table[] = {
 202        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 203        9600, 19200, 38400, 57600, 115200, 230400, 460800,
 204#ifdef __sparc__
 205        76800, 153600, 307200, 614400, 921600
 206#else
 207        500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
 208        2500000, 3000000, 3500000, 4000000
 209#endif
 210};
 211
 212#ifndef __sparc__
 213static const tcflag_t baud_bits[] = {
 214        B0, B50, B75, B110, B134, B150, B200, B300, B600,
 215        B1200, B1800, B2400, B4800, B9600, B19200, B38400,
 216        B57600, B115200, B230400, B460800, B500000, B576000,
 217        B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
 218        B3000000, B3500000, B4000000
 219};
 220#else
 221static const tcflag_t baud_bits[] = {
 222        B0, B50, B75, B110, B134, B150, B200, B300, B600,
 223        B1200, B1800, B2400, B4800, B9600, B19200, B38400,
 224        B57600, B115200, B230400, B460800, B76800, B153600,
 225        B307200, B614400, B921600
 226};
 227#endif
 228
 229static int n_baud_table = ARRAY_SIZE(baud_table);
 230
 231/**
 232 *      tty_termios_baud_rate
 233 *      @termios: termios structure
 234 *
 235 *      Convert termios baud rate data into a speed. This should be called
 236 *      with the termios lock held if this termios is a terminal termios
 237 *      structure. May change the termios data. Device drivers can call this
 238 *      function but should use ->c_[io]speed directly as they are updated.
 239 *
 240 *      Locking: none
 241 */
 242
 243speed_t tty_termios_baud_rate(struct ktermios *termios)
 244{
 245        unsigned int cbaud;
 246
 247        cbaud = termios->c_cflag & CBAUD;
 248
 249#ifdef BOTHER
 250        /* Magic token for arbitary speed via c_ispeed/c_ospeed */
 251        if (cbaud == BOTHER)
 252                return termios->c_ospeed;
 253#endif
 254        if (cbaud & CBAUDEX) {
 255                cbaud &= ~CBAUDEX;
 256
 257                if (cbaud < 1 || cbaud + 15 > n_baud_table)
 258                        termios->c_cflag &= ~CBAUDEX;
 259                else
 260                        cbaud += 15;
 261        }
 262        return baud_table[cbaud];
 263}
 264EXPORT_SYMBOL(tty_termios_baud_rate);
 265
 266/**
 267 *      tty_termios_input_baud_rate
 268 *      @termios: termios structure
 269 *
 270 *      Convert termios baud rate data into a speed. This should be called
 271 *      with the termios lock held if this termios is a terminal termios
 272 *      structure. May change the termios data. Device drivers can call this
 273 *      function but should use ->c_[io]speed directly as they are updated.
 274 *
 275 *      Locking: none
 276 */
 277
 278speed_t tty_termios_input_baud_rate(struct ktermios *termios)
 279{
 280#ifdef IBSHIFT
 281        unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
 282
 283        if (cbaud == B0)
 284                return tty_termios_baud_rate(termios);
 285
 286        /* Magic token for arbitary speed via c_ispeed*/
 287        if (cbaud == BOTHER)
 288                return termios->c_ispeed;
 289
 290        if (cbaud & CBAUDEX) {
 291                cbaud &= ~CBAUDEX;
 292
 293                if (cbaud < 1 || cbaud + 15 > n_baud_table)
 294                        termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
 295                else
 296                        cbaud += 15;
 297        }
 298        return baud_table[cbaud];
 299#else
 300        return tty_termios_baud_rate(termios);
 301#endif
 302}
 303EXPORT_SYMBOL(tty_termios_input_baud_rate);
 304
 305/**
 306 *      tty_termios_encode_baud_rate
 307 *      @termios: ktermios structure holding user requested state
 308 *      @ispeed: input speed
 309 *      @ospeed: output speed
 310 *
 311 *      Encode the speeds set into the passed termios structure. This is
 312 *      used as a library helper for drivers os that they can report back
 313 *      the actual speed selected when it differs from the speed requested
 314 *
 315 *      For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
 316 *      we need to carefully set the bits when the user does not get the
 317 *      desired speed. We allow small margins and preserve as much of possible
 318 *      of the input intent to keep compatiblity.
 319 *
 320 *      Locking: Caller should hold termios lock. This is already held
 321 *      when calling this function from the driver termios handler.
 322 *
 323 *      The ifdefs deal with platforms whose owners have yet to update them
 324 *      and will all go away once this is done.
 325 */
 326
 327void tty_termios_encode_baud_rate(struct ktermios *termios,
 328                                  speed_t ibaud, speed_t obaud)
 329{
 330        int i = 0;
 331        int ifound = -1, ofound = -1;
 332        int iclose = ibaud/50, oclose = obaud/50;
 333        int ibinput = 0;
 334
 335        if (obaud == 0)                 /* CD dropped             */
 336                ibaud = 0;              /* Clear ibaud to be sure */
 337
 338        termios->c_ispeed = ibaud;
 339        termios->c_ospeed = obaud;
 340
 341#ifdef BOTHER
 342        /* If the user asked for a precise weird speed give a precise weird
 343           answer. If they asked for a Bfoo speed they many have problems
 344           digesting non-exact replies so fuzz a bit */
 345
 346        if ((termios->c_cflag & CBAUD) == BOTHER)
 347                oclose = 0;
 348        if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
 349                iclose = 0;
 350        if ((termios->c_cflag >> IBSHIFT) & CBAUD)
 351                ibinput = 1;    /* An input speed was specified */
 352#endif
 353        termios->c_cflag &= ~CBAUD;
 354
 355        /*
 356         *      Our goal is to find a close match to the standard baud rate
 357         *      returned. Walk the baud rate table and if we get a very close
 358         *      match then report back the speed as a POSIX Bxxxx value by
 359         *      preference
 360         */
 361
 362        do {
 363                if (obaud - oclose <= baud_table[i] &&
 364                    obaud + oclose >= baud_table[i]) {
 365                        termios->c_cflag |= baud_bits[i];
 366                        ofound = i;
 367                }
 368                if (ibaud - iclose <= baud_table[i] &&
 369                    ibaud + iclose >= baud_table[i]) {
 370                        /* For the case input == output don't set IBAUD bits
 371                           if the user didn't do so */
 372                        if (ofound == i && !ibinput)
 373                                ifound  = i;
 374#ifdef IBSHIFT
 375                        else {
 376                                ifound = i;
 377                                termios->c_cflag |= (baud_bits[i] << IBSHIFT);
 378                        }
 379#endif
 380                }
 381        } while (++i < n_baud_table);
 382
 383        /*
 384         *      If we found no match then use BOTHER if provided or warn
 385         *      the user their platform maintainer needs to wake up if not.
 386         */
 387#ifdef BOTHER
 388        if (ofound == -1)
 389                termios->c_cflag |= BOTHER;
 390        /* Set exact input bits only if the input and output differ or the
 391           user already did */
 392        if (ifound == -1 && (ibaud != obaud || ibinput))
 393                termios->c_cflag |= (BOTHER << IBSHIFT);
 394#else
 395        if (ifound == -1 || ofound == -1) {
 396                printk_once(KERN_WARNING "tty: Unable to return correct "
 397                          "speed data as your architecture needs updating.\n");
 398        }
 399#endif
 400}
 401EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
 402
 403/**
 404 *      tty_encode_baud_rate            -       set baud rate of the tty
 405 *      @ibaud: input baud rate
 406 *      @obad: output baud rate
 407 *
 408 *      Update the current termios data for the tty with the new speed
 409 *      settings. The caller must hold the termios_mutex for the tty in
 410 *      question.
 411 */
 412
 413void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
 414{
 415        tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
 416}
 417EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
 418
 419/**
 420 *      tty_get_baud_rate       -       get tty bit rates
 421 *      @tty: tty to query
 422 *
 423 *      Returns the baud rate as an integer for this terminal. The
 424 *      termios lock must be held by the caller and the terminal bit
 425 *      flags may be updated.
 426 *
 427 *      Locking: none
 428 */
 429
 430speed_t tty_get_baud_rate(struct tty_struct *tty)
 431{
 432        speed_t baud = tty_termios_baud_rate(tty->termios);
 433
 434        if (baud == 38400 && tty->alt_speed) {
 435                if (!tty->warned) {
 436                        printk(KERN_WARNING "Use of setserial/setrocket to "
 437                                            "set SPD_* flags is deprecated\n");
 438                        tty->warned = 1;
 439                }
 440                baud = tty->alt_speed;
 441        }
 442
 443        return baud;
 444}
 445EXPORT_SYMBOL(tty_get_baud_rate);
 446
 447/**
 448 *      tty_termios_copy_hw     -       copy hardware settings
 449 *      @new: New termios
 450 *      @old: Old termios
 451 *
 452 *      Propogate the hardware specific terminal setting bits from
 453 *      the old termios structure to the new one. This is used in cases
 454 *      where the hardware does not support reconfiguration or as a helper
 455 *      in some cases where only minimal reconfiguration is supported
 456 */
 457
 458void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
 459{
 460        /* The bits a dumb device handles in software. Smart devices need
 461           to always provide a set_termios method */
 462        new->c_cflag &= HUPCL | CREAD | CLOCAL;
 463        new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
 464        new->c_ispeed = old->c_ispeed;
 465        new->c_ospeed = old->c_ospeed;
 466}
 467EXPORT_SYMBOL(tty_termios_copy_hw);
 468
 469/**
 470 *      tty_termios_hw_change   -       check for setting change
 471 *      @a: termios
 472 *      @b: termios to compare
 473 *
 474 *      Check if any of the bits that affect a dumb device have changed
 475 *      between the two termios structures, or a speed change is needed.
 476 */
 477
 478int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
 479{
 480        if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
 481                return 1;
 482        if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
 483                return 1;
 484        return 0;
 485}
 486EXPORT_SYMBOL(tty_termios_hw_change);
 487
 488/**
 489 *      change_termios          -       update termios values
 490 *      @tty: tty to update
 491 *      @new_termios: desired new value
 492 *
 493 *      Perform updates to the termios values set on this terminal. There
 494 *      is a bit of layering violation here with n_tty in terms of the
 495 *      internal knowledge of this function.
 496 *
 497 *      Locking: termios_mutex
 498 */
 499
 500static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
 501{
 502        struct ktermios old_termios;
 503        struct tty_ldisc *ld;
 504        unsigned long flags;
 505
 506        /*
 507         *      Perform the actual termios internal changes under lock.
 508         */
 509
 510
 511        /* FIXME: we need to decide on some locking/ordering semantics
 512           for the set_termios notification eventually */
 513        mutex_lock(&tty->termios_mutex);
 514        old_termios = *tty->termios;
 515        *tty->termios = *new_termios;
 516        unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
 517
 518        /* See if packet mode change of state. */
 519        if (tty->link && tty->link->packet) {
 520                int old_flow = ((old_termios.c_iflag & IXON) &&
 521                                (old_termios.c_cc[VSTOP] == '\023') &&
 522                                (old_termios.c_cc[VSTART] == '\021'));
 523                int new_flow = (I_IXON(tty) &&
 524                                STOP_CHAR(tty) == '\023' &&
 525                                START_CHAR(tty) == '\021');
 526                if (old_flow != new_flow) {
 527                        spin_lock_irqsave(&tty->ctrl_lock, flags);
 528                        tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
 529                        if (new_flow)
 530                                tty->ctrl_status |= TIOCPKT_DOSTOP;
 531                        else
 532                                tty->ctrl_status |= TIOCPKT_NOSTOP;
 533                        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 534                        wake_up_interruptible(&tty->link->read_wait);
 535                }
 536        }
 537
 538        if (tty->ops->set_termios)
 539                (*tty->ops->set_termios)(tty, &old_termios);
 540        else
 541                tty_termios_copy_hw(tty->termios, &old_termios);
 542
 543        ld = tty_ldisc_ref(tty);
 544        if (ld != NULL) {
 545                if (ld->ops->set_termios)
 546                        (ld->ops->set_termios)(tty, &old_termios);
 547                tty_ldisc_deref(ld);
 548        }
 549        mutex_unlock(&tty->termios_mutex);
 550}
 551
 552/**
 553 *      set_termios             -       set termios values for a tty
 554 *      @tty: terminal device
 555 *      @arg: user data
 556 *      @opt: option information
 557 *
 558 *      Helper function to prepare termios data and run necessary other
 559 *      functions before using change_termios to do the actual changes.
 560 *
 561 *      Locking:
 562 *              Called functions take ldisc and termios_mutex locks
 563 */
 564
 565static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
 566{
 567        struct ktermios tmp_termios;
 568        struct tty_ldisc *ld;
 569        int retval = tty_check_change(tty);
 570
 571        if (retval)
 572                return retval;
 573
 574        mutex_lock(&tty->termios_mutex);
 575        memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
 576        mutex_unlock(&tty->termios_mutex);
 577
 578        if (opt & TERMIOS_TERMIO) {
 579                if (user_termio_to_kernel_termios(&tmp_termios,
 580                                                (struct termio __user *)arg))
 581                        return -EFAULT;
 582#ifdef TCGETS2
 583        } else if (opt & TERMIOS_OLD) {
 584                if (user_termios_to_kernel_termios_1(&tmp_termios,
 585                                                (struct termios __user *)arg))
 586                        return -EFAULT;
 587        } else {
 588                if (user_termios_to_kernel_termios(&tmp_termios,
 589                                                (struct termios2 __user *)arg))
 590                        return -EFAULT;
 591        }
 592#else
 593        } else if (user_termios_to_kernel_termios(&tmp_termios,
 594                                        (struct termios __user *)arg))
 595                return -EFAULT;
 596#endif
 597
 598        /* If old style Bfoo values are used then load c_ispeed/c_ospeed
 599         * with the real speed so its unconditionally usable */
 600        tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
 601        tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
 602
 603        ld = tty_ldisc_ref(tty);
 604
 605        if (ld != NULL) {
 606                if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
 607                        ld->ops->flush_buffer(tty);
 608                tty_ldisc_deref(ld);
 609        }
 610
 611        if (opt & TERMIOS_WAIT) {
 612                tty_wait_until_sent(tty, 0);
 613                if (signal_pending(current))
 614                        return -EINTR;
 615        }
 616
 617        change_termios(tty, &tmp_termios);
 618
 619        /* FIXME: Arguably if tmp_termios == tty->termios AND the
 620           actual requested termios was not tmp_termios then we may
 621           want to return an error as no user requested change has
 622           succeeded */
 623        return 0;
 624}
 625
 626static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
 627{
 628        mutex_lock(&tty->termios_mutex);
 629        memcpy(kterm, tty->termios, sizeof(struct ktermios));
 630        mutex_unlock(&tty->termios_mutex);
 631}
 632
 633static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
 634{
 635        mutex_lock(&tty->termios_mutex);
 636        memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
 637        mutex_unlock(&tty->termios_mutex);
 638}
 639
 640static int get_termio(struct tty_struct *tty, struct termio __user *termio)
 641{
 642        struct ktermios kterm;
 643        copy_termios(tty, &kterm);
 644        if (kernel_termios_to_user_termio(termio, &kterm))
 645                return -EFAULT;
 646        return 0;
 647}
 648
 649
 650#ifdef TCGETX
 651
 652/**
 653 *      set_termiox     -       set termiox fields if possible
 654 *      @tty: terminal
 655 *      @arg: termiox structure from user
 656 *      @opt: option flags for ioctl type
 657 *
 658 *      Implement the device calling points for the SYS5 termiox ioctl
 659 *      interface in Linux
 660 */
 661
 662static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
 663{
 664        struct termiox tnew;
 665        struct tty_ldisc *ld;
 666
 667        if (tty->termiox == NULL)
 668                return -EINVAL;
 669        if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
 670                return -EFAULT;
 671
 672        ld = tty_ldisc_ref(tty);
 673        if (ld != NULL) {
 674                if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
 675                        ld->ops->flush_buffer(tty);
 676                tty_ldisc_deref(ld);
 677        }
 678        if (opt & TERMIOS_WAIT) {
 679                tty_wait_until_sent(tty, 0);
 680                if (signal_pending(current))
 681                        return -EINTR;
 682        }
 683
 684        mutex_lock(&tty->termios_mutex);
 685        if (tty->ops->set_termiox)
 686                tty->ops->set_termiox(tty, &tnew);
 687        mutex_unlock(&tty->termios_mutex);
 688        return 0;
 689}
 690
 691#endif
 692
 693
 694#ifdef TIOCGETP
 695/*
 696 * These are deprecated, but there is limited support..
 697 *
 698 * The "sg_flags" translation is a joke..
 699 */
 700static int get_sgflags(struct tty_struct *tty)
 701{
 702        int flags = 0;
 703
 704        if (!(tty->termios->c_lflag & ICANON)) {
 705                if (tty->termios->c_lflag & ISIG)
 706                        flags |= 0x02;          /* cbreak */
 707                else
 708                        flags |= 0x20;          /* raw */
 709        }
 710        if (tty->termios->c_lflag & ECHO)
 711                flags |= 0x08;                  /* echo */
 712        if (tty->termios->c_oflag & OPOST)
 713                if (tty->termios->c_oflag & ONLCR)
 714                        flags |= 0x10;          /* crmod */
 715        return flags;
 716}
 717
 718static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
 719{
 720        struct sgttyb tmp;
 721
 722        mutex_lock(&tty->termios_mutex);
 723        tmp.sg_ispeed = tty->termios->c_ispeed;
 724        tmp.sg_ospeed = tty->termios->c_ospeed;
 725        tmp.sg_erase = tty->termios->c_cc[VERASE];
 726        tmp.sg_kill = tty->termios->c_cc[VKILL];
 727        tmp.sg_flags = get_sgflags(tty);
 728        mutex_unlock(&tty->termios_mutex);
 729
 730        return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 731}
 732
 733static void set_sgflags(struct ktermios *termios, int flags)
 734{
 735        termios->c_iflag = ICRNL | IXON;
 736        termios->c_oflag = 0;
 737        termios->c_lflag = ISIG | ICANON;
 738        if (flags & 0x02) {     /* cbreak */
 739                termios->c_iflag = 0;
 740                termios->c_lflag &= ~ICANON;
 741        }
 742        if (flags & 0x08) {             /* echo */
 743                termios->c_lflag |= ECHO | ECHOE | ECHOK |
 744                                    ECHOCTL | ECHOKE | IEXTEN;
 745        }
 746        if (flags & 0x10) {             /* crmod */
 747                termios->c_oflag |= OPOST | ONLCR;
 748        }
 749        if (flags & 0x20) {     /* raw */
 750                termios->c_iflag = 0;
 751                termios->c_lflag &= ~(ISIG | ICANON);
 752        }
 753        if (!(termios->c_lflag & ICANON)) {
 754                termios->c_cc[VMIN] = 1;
 755                termios->c_cc[VTIME] = 0;
 756        }
 757}
 758
 759/**
 760 *      set_sgttyb              -       set legacy terminal values
 761 *      @tty: tty structure
 762 *      @sgttyb: pointer to old style terminal structure
 763 *
 764 *      Updates a terminal from the legacy BSD style terminal information
 765 *      structure.
 766 *
 767 *      Locking: termios_mutex
 768 */
 769
 770static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
 771{
 772        int retval;
 773        struct sgttyb tmp;
 774        struct ktermios termios;
 775
 776        retval = tty_check_change(tty);
 777        if (retval)
 778                return retval;
 779
 780        if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
 781                return -EFAULT;
 782
 783        mutex_lock(&tty->termios_mutex);
 784        termios = *tty->termios;
 785        termios.c_cc[VERASE] = tmp.sg_erase;
 786        termios.c_cc[VKILL] = tmp.sg_kill;
 787        set_sgflags(&termios, tmp.sg_flags);
 788        /* Try and encode into Bfoo format */
 789#ifdef BOTHER
 790        tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
 791                                                termios.c_ospeed);
 792#endif
 793        mutex_unlock(&tty->termios_mutex);
 794        change_termios(tty, &termios);
 795        return 0;
 796}
 797#endif
 798
 799#ifdef TIOCGETC
 800static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
 801{
 802        struct tchars tmp;
 803
 804        mutex_lock(&tty->termios_mutex);
 805        tmp.t_intrc = tty->termios->c_cc[VINTR];
 806        tmp.t_quitc = tty->termios->c_cc[VQUIT];
 807        tmp.t_startc = tty->termios->c_cc[VSTART];
 808        tmp.t_stopc = tty->termios->c_cc[VSTOP];
 809        tmp.t_eofc = tty->termios->c_cc[VEOF];
 810        tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
 811        mutex_unlock(&tty->termios_mutex);
 812        return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 813}
 814
 815static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
 816{
 817        struct tchars tmp;
 818
 819        if (copy_from_user(&tmp, tchars, sizeof(tmp)))
 820                return -EFAULT;
 821        mutex_lock(&tty->termios_mutex);
 822        tty->termios->c_cc[VINTR] = tmp.t_intrc;
 823        tty->termios->c_cc[VQUIT] = tmp.t_quitc;
 824        tty->termios->c_cc[VSTART] = tmp.t_startc;
 825        tty->termios->c_cc[VSTOP] = tmp.t_stopc;
 826        tty->termios->c_cc[VEOF] = tmp.t_eofc;
 827        tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
 828        mutex_unlock(&tty->termios_mutex);
 829        return 0;
 830}
 831#endif
 832
 833#ifdef TIOCGLTC
 834static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
 835{
 836        struct ltchars tmp;
 837
 838        mutex_lock(&tty->termios_mutex);
 839        tmp.t_suspc = tty->termios->c_cc[VSUSP];
 840        /* what is dsuspc anyway? */
 841        tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
 842        tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
 843        /* what is flushc anyway? */
 844        tmp.t_flushc = tty->termios->c_cc[VEOL2];
 845        tmp.t_werasc = tty->termios->c_cc[VWERASE];
 846        tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
 847        mutex_unlock(&tty->termios_mutex);
 848        return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 849}
 850
 851static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
 852{
 853        struct ltchars tmp;
 854
 855        if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
 856                return -EFAULT;
 857
 858        mutex_lock(&tty->termios_mutex);
 859        tty->termios->c_cc[VSUSP] = tmp.t_suspc;
 860        /* what is dsuspc anyway? */
 861        tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
 862        tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
 863        /* what is flushc anyway? */
 864        tty->termios->c_cc[VEOL2] = tmp.t_flushc;
 865        tty->termios->c_cc[VWERASE] = tmp.t_werasc;
 866        tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
 867        mutex_unlock(&tty->termios_mutex);
 868        return 0;
 869}
 870#endif
 871
 872/**
 873 *      send_prio_char          -       send priority character
 874 *
 875 *      Send a high priority character to the tty even if stopped
 876 *
 877 *      Locking: none for xchar method, write ordering for write method.
 878 */
 879
 880static int send_prio_char(struct tty_struct *tty, char ch)
 881{
 882        int     was_stopped = tty->stopped;
 883
 884        if (tty->ops->send_xchar) {
 885                tty->ops->send_xchar(tty, ch);
 886                return 0;
 887        }
 888
 889        if (tty_write_lock(tty, 0) < 0)
 890                return -ERESTARTSYS;
 891
 892        if (was_stopped)
 893                start_tty(tty);
 894        tty->ops->write(tty, &ch, 1);
 895        if (was_stopped)
 896                stop_tty(tty);
 897        tty_write_unlock(tty);
 898        return 0;
 899}
 900
 901/**
 902 *      tty_change_softcar      -       carrier change ioctl helper
 903 *      @tty: tty to update
 904 *      @arg: enable/disable CLOCAL
 905 *
 906 *      Perform a change to the CLOCAL state and call into the driver
 907 *      layer to make it visible. All done with the termios mutex
 908 */
 909
 910static int tty_change_softcar(struct tty_struct *tty, int arg)
 911{
 912        int ret = 0;
 913        int bit = arg ? CLOCAL : 0;
 914        struct ktermios old;
 915
 916        mutex_lock(&tty->termios_mutex);
 917        old = *tty->termios;
 918        tty->termios->c_cflag &= ~CLOCAL;
 919        tty->termios->c_cflag |= bit;
 920        if (tty->ops->set_termios)
 921                tty->ops->set_termios(tty, &old);
 922        if ((tty->termios->c_cflag & CLOCAL) != bit)
 923                ret = -EINVAL;
 924        mutex_unlock(&tty->termios_mutex);
 925        return ret;
 926}
 927
 928/**
 929 *      tty_mode_ioctl          -       mode related ioctls
 930 *      @tty: tty for the ioctl
 931 *      @file: file pointer for the tty
 932 *      @cmd: command
 933 *      @arg: ioctl argument
 934 *
 935 *      Perform non line discipline specific mode control ioctls. This
 936 *      is designed to be called by line disciplines to ensure they provide
 937 *      consistent mode setting.
 938 */
 939
 940int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
 941                        unsigned int cmd, unsigned long arg)
 942{
 943        struct tty_struct *real_tty;
 944        void __user *p = (void __user *)arg;
 945        int ret = 0;
 946        struct ktermios kterm;
 947
 948        if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
 949            tty->driver->subtype == PTY_TYPE_MASTER)
 950                real_tty = tty->link;
 951        else
 952                real_tty = tty;
 953
 954        switch (cmd) {
 955#ifdef TIOCGETP
 956        case TIOCGETP:
 957                return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
 958        case TIOCSETP:
 959        case TIOCSETN:
 960                return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
 961#endif
 962#ifdef TIOCGETC
 963        case TIOCGETC:
 964                return get_tchars(real_tty, p);
 965        case TIOCSETC:
 966                return set_tchars(real_tty, p);
 967#endif
 968#ifdef TIOCGLTC
 969        case TIOCGLTC:
 970                return get_ltchars(real_tty, p);
 971        case TIOCSLTC:
 972                return set_ltchars(real_tty, p);
 973#endif
 974        case TCSETSF:
 975                return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
 976        case TCSETSW:
 977                return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
 978        case TCSETS:
 979                return set_termios(real_tty, p, TERMIOS_OLD);
 980#ifndef TCGETS2
 981        case TCGETS:
 982                copy_termios(real_tty, &kterm);
 983                if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
 984                        ret = -EFAULT;
 985                return ret;
 986#else
 987        case TCGETS:
 988                copy_termios(real_tty, &kterm);
 989                if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
 990                        ret = -EFAULT;
 991                return ret;
 992        case TCGETS2:
 993                copy_termios(real_tty, &kterm);
 994                if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
 995                        ret = -EFAULT;
 996                return ret;
 997        case TCSETSF2:
 998                return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
 999        case TCSETSW2:
1000                return set_termios(real_tty, p, TERMIOS_WAIT);
1001        case TCSETS2:
1002                return set_termios(real_tty, p, 0);
1003#endif
1004        case TCGETA:
1005                return get_termio(real_tty, p);
1006        case TCSETAF:
1007                return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
1008        case TCSETAW:
1009                return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
1010        case TCSETA:
1011                return set_termios(real_tty, p, TERMIOS_TERMIO);
1012#ifndef TCGETS2
1013        case TIOCGLCKTRMIOS:
1014                copy_termios_locked(real_tty, &kterm);
1015                if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
1016                        ret = -EFAULT;
1017                return ret;
1018        case TIOCSLCKTRMIOS:
1019                if (!capable(CAP_SYS_ADMIN))
1020                        return -EPERM;
1021                copy_termios_locked(real_tty, &kterm);
1022                if (user_termios_to_kernel_termios(&kterm,
1023                                               (struct termios __user *) arg))
1024                        return -EFAULT;
1025                mutex_lock(&real_tty->termios_mutex);
1026                memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1027                mutex_unlock(&real_tty->termios_mutex);
1028                return 0;
1029#else
1030        case TIOCGLCKTRMIOS:
1031                copy_termios_locked(real_tty, &kterm);
1032                if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1033                        ret = -EFAULT;
1034                return ret;
1035        case TIOCSLCKTRMIOS:
1036                if (!capable(CAP_SYS_ADMIN))
1037                        return -EPERM;
1038                copy_termios_locked(real_tty, &kterm);
1039                if (user_termios_to_kernel_termios_1(&kterm,
1040                                               (struct termios __user *) arg))
1041                        return -EFAULT;
1042                mutex_lock(&real_tty->termios_mutex);
1043                memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1044                mutex_unlock(&real_tty->termios_mutex);
1045                return ret;
1046#endif
1047#ifdef TCGETX
1048        case TCGETX: {
1049                struct termiox ktermx;
1050                if (real_tty->termiox == NULL)
1051                        return -EINVAL;
1052                mutex_lock(&real_tty->termios_mutex);
1053                memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
1054                mutex_unlock(&real_tty->termios_mutex);
1055                if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
1056                        ret = -EFAULT;
1057                return ret;
1058        }
1059        case TCSETX:
1060                return set_termiox(real_tty, p, 0);
1061        case TCSETXW:
1062                return set_termiox(real_tty, p, TERMIOS_WAIT);
1063        case TCSETXF:
1064                return set_termiox(real_tty, p, TERMIOS_FLUSH);
1065#endif          
1066        case TIOCGSOFTCAR:
1067                copy_termios(real_tty, &kterm);
1068                ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
1069                                                (int __user *)arg);
1070                return ret;
1071        case TIOCSSOFTCAR:
1072                if (get_user(arg, (unsigned int __user *) arg))
1073                        return -EFAULT;
1074                return tty_change_softcar(real_tty, arg);
1075        default:
1076                return -ENOIOCTLCMD;
1077        }
1078}
1079EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1080
1081int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1082{
1083        struct tty_ldisc *ld;
1084        int retval = tty_check_change(tty);
1085        if (retval)
1086                return retval;
1087
1088        ld = tty_ldisc_ref_wait(tty);
1089        switch (arg) {
1090        case TCIFLUSH:
1091                if (ld && ld->ops->flush_buffer)
1092                        ld->ops->flush_buffer(tty);
1093                break;
1094        case TCIOFLUSH:
1095                if (ld && ld->ops->flush_buffer)
1096                        ld->ops->flush_buffer(tty);
1097                /* fall through */
1098        case TCOFLUSH:
1099                tty_driver_flush_buffer(tty);
1100                break;
1101        default:
1102                tty_ldisc_deref(ld);
1103                return -EINVAL;
1104        }
1105        tty_ldisc_deref(ld);
1106        return 0;
1107}
1108EXPORT_SYMBOL_GPL(tty_perform_flush);
1109
1110int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
1111                       unsigned int cmd, unsigned long arg)
1112{
1113        unsigned long flags;
1114        int retval;
1115
1116        switch (cmd) {
1117        case TCXONC:
1118                retval = tty_check_change(tty);
1119                if (retval)
1120                        return retval;
1121                switch (arg) {
1122                case TCOOFF:
1123                        if (!tty->flow_stopped) {
1124                                tty->flow_stopped = 1;
1125                                stop_tty(tty);
1126                        }
1127                        break;
1128                case TCOON:
1129                        if (tty->flow_stopped) {
1130                                tty->flow_stopped = 0;
1131                                start_tty(tty);
1132                        }
1133                        break;
1134                case TCIOFF:
1135                        if (STOP_CHAR(tty) != __DISABLED_CHAR)
1136                                return send_prio_char(tty, STOP_CHAR(tty));
1137                        break;
1138                case TCION:
1139                        if (START_CHAR(tty) != __DISABLED_CHAR)
1140                                return send_prio_char(tty, START_CHAR(tty));
1141                        break;
1142                default:
1143                        return -EINVAL;
1144                }
1145                return 0;
1146        case TCFLSH:
1147                return tty_perform_flush(tty, arg);
1148        case TIOCPKT:
1149        {
1150                int pktmode;
1151
1152                if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1153                    tty->driver->subtype != PTY_TYPE_MASTER)
1154                        return -ENOTTY;
1155                if (get_user(pktmode, (int __user *) arg))
1156                        return -EFAULT;
1157                spin_lock_irqsave(&tty->ctrl_lock, flags);
1158                if (pktmode) {
1159                        if (!tty->packet) {
1160                                tty->packet = 1;
1161                                tty->link->ctrl_status = 0;
1162                        }
1163                } else
1164                        tty->packet = 0;
1165                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1166                return 0;
1167        }
1168        default:
1169                /* Try the mode commands */
1170                return tty_mode_ioctl(tty, file, cmd, arg);
1171        }
1172}
1173EXPORT_SYMBOL(n_tty_ioctl_helper);
1174