linux/drivers/tty/tty_ldisc.c
<<
>>
Prefs
   1#include <linux/types.h>
   2#include <linux/errno.h>
   3#include <linux/kmod.h>
   4#include <linux/sched.h>
   5#include <linux/interrupt.h>
   6#include <linux/tty.h>
   7#include <linux/tty_driver.h>
   8#include <linux/file.h>
   9#include <linux/mm.h>
  10#include <linux/string.h>
  11#include <linux/slab.h>
  12#include <linux/poll.h>
  13#include <linux/proc_fs.h>
  14#include <linux/module.h>
  15#include <linux/device.h>
  16#include <linux/wait.h>
  17#include <linux/bitops.h>
  18#include <linux/seq_file.h>
  19#include <linux/uaccess.h>
  20#include <linux/ratelimit.h>
  21
  22#undef LDISC_DEBUG_HANGUP
  23
  24#ifdef LDISC_DEBUG_HANGUP
  25#define tty_ldisc_debug(tty, f, args...)        tty_debug(tty, f, ##args)
  26#else
  27#define tty_ldisc_debug(tty, f, args...)
  28#endif
  29
  30/* lockdep nested classes for tty->ldisc_sem */
  31enum {
  32        LDISC_SEM_NORMAL,
  33        LDISC_SEM_OTHER,
  34};
  35
  36
  37/*
  38 *      This guards the refcounted line discipline lists. The lock
  39 *      must be taken with irqs off because there are hangup path
  40 *      callers who will do ldisc lookups and cannot sleep.
  41 */
  42
  43static DEFINE_RAW_SPINLOCK(tty_ldiscs_lock);
  44/* Line disc dispatch table */
  45static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
  46
  47/**
  48 *      tty_register_ldisc      -       install a line discipline
  49 *      @disc: ldisc number
  50 *      @new_ldisc: pointer to the ldisc object
  51 *
  52 *      Installs a new line discipline into the kernel. The discipline
  53 *      is set up as unreferenced and then made available to the kernel
  54 *      from this point onwards.
  55 *
  56 *      Locking:
  57 *              takes tty_ldiscs_lock to guard against ldisc races
  58 */
  59
  60int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
  61{
  62        unsigned long flags;
  63        int ret = 0;
  64
  65        if (disc < N_TTY || disc >= NR_LDISCS)
  66                return -EINVAL;
  67
  68        raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
  69        tty_ldiscs[disc] = new_ldisc;
  70        new_ldisc->num = disc;
  71        new_ldisc->refcount = 0;
  72        raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
  73
  74        return ret;
  75}
  76EXPORT_SYMBOL(tty_register_ldisc);
  77
  78/**
  79 *      tty_unregister_ldisc    -       unload a line discipline
  80 *      @disc: ldisc number
  81 *      @new_ldisc: pointer to the ldisc object
  82 *
  83 *      Remove a line discipline from the kernel providing it is not
  84 *      currently in use.
  85 *
  86 *      Locking:
  87 *              takes tty_ldiscs_lock to guard against ldisc races
  88 */
  89
  90int tty_unregister_ldisc(int disc)
  91{
  92        unsigned long flags;
  93        int ret = 0;
  94
  95        if (disc < N_TTY || disc >= NR_LDISCS)
  96                return -EINVAL;
  97
  98        raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
  99        if (tty_ldiscs[disc]->refcount)
 100                ret = -EBUSY;
 101        else
 102                tty_ldiscs[disc] = NULL;
 103        raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
 104
 105        return ret;
 106}
 107EXPORT_SYMBOL(tty_unregister_ldisc);
 108
 109static struct tty_ldisc_ops *get_ldops(int disc)
 110{
 111        unsigned long flags;
 112        struct tty_ldisc_ops *ldops, *ret;
 113
 114        raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
 115        ret = ERR_PTR(-EINVAL);
 116        ldops = tty_ldiscs[disc];
 117        if (ldops) {
 118                ret = ERR_PTR(-EAGAIN);
 119                if (try_module_get(ldops->owner)) {
 120                        ldops->refcount++;
 121                        ret = ldops;
 122                }
 123        }
 124        raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
 125        return ret;
 126}
 127
 128static void put_ldops(struct tty_ldisc_ops *ldops)
 129{
 130        unsigned long flags;
 131
 132        raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
 133        ldops->refcount--;
 134        module_put(ldops->owner);
 135        raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
 136}
 137
 138/**
 139 *      tty_ldisc_get           -       take a reference to an ldisc
 140 *      @disc: ldisc number
 141 *
 142 *      Takes a reference to a line discipline. Deals with refcounts and
 143 *      module locking counts.
 144 *
 145 *      Returns: -EINVAL if the discipline index is not [N_TTY..NR_LDISCS] or
 146 *                       if the discipline is not registered
 147 *               -EAGAIN if request_module() failed to load or register the
 148 *                       the discipline
 149 *               -ENOMEM if allocation failure
 150 *
 151 *               Otherwise, returns a pointer to the discipline and bumps the
 152 *               ref count
 153 *
 154 *      Locking:
 155 *              takes tty_ldiscs_lock to guard against ldisc races
 156 */
 157
 158static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
 159{
 160        struct tty_ldisc *ld;
 161        struct tty_ldisc_ops *ldops;
 162
 163        if (disc < N_TTY || disc >= NR_LDISCS)
 164                return ERR_PTR(-EINVAL);
 165
 166        /*
 167         * Get the ldisc ops - we may need to request them to be loaded
 168         * dynamically and try again.
 169         */
 170        ldops = get_ldops(disc);
 171        if (IS_ERR(ldops)) {
 172                request_module("tty-ldisc-%d", disc);
 173                ldops = get_ldops(disc);
 174                if (IS_ERR(ldops))
 175                        return ERR_CAST(ldops);
 176        }
 177
 178        ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
 179        if (ld == NULL) {
 180                put_ldops(ldops);
 181                return ERR_PTR(-ENOMEM);
 182        }
 183
 184        ld->ops = ldops;
 185        ld->tty = tty;
 186
 187        return ld;
 188}
 189
 190/**
 191 *      tty_ldisc_put           -       release the ldisc
 192 *
 193 *      Complement of tty_ldisc_get().
 194 */
 195static void tty_ldisc_put(struct tty_ldisc *ld)
 196{
 197        if (WARN_ON_ONCE(!ld))
 198                return;
 199
 200        put_ldops(ld->ops);
 201        kfree(ld);
 202}
 203
 204static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
 205{
 206        return (*pos < NR_LDISCS) ? pos : NULL;
 207}
 208
 209static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
 210{
 211        (*pos)++;
 212        return (*pos < NR_LDISCS) ? pos : NULL;
 213}
 214
 215static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
 216{
 217}
 218
 219static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
 220{
 221        int i = *(loff_t *)v;
 222        struct tty_ldisc_ops *ldops;
 223
 224        ldops = get_ldops(i);
 225        if (IS_ERR(ldops))
 226                return 0;
 227        seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
 228        put_ldops(ldops);
 229        return 0;
 230}
 231
 232static const struct seq_operations tty_ldiscs_seq_ops = {
 233        .start  = tty_ldiscs_seq_start,
 234        .next   = tty_ldiscs_seq_next,
 235        .stop   = tty_ldiscs_seq_stop,
 236        .show   = tty_ldiscs_seq_show,
 237};
 238
 239static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
 240{
 241        return seq_open(file, &tty_ldiscs_seq_ops);
 242}
 243
 244const struct file_operations tty_ldiscs_proc_fops = {
 245        .owner          = THIS_MODULE,
 246        .open           = proc_tty_ldiscs_open,
 247        .read           = seq_read,
 248        .llseek         = seq_lseek,
 249        .release        = seq_release,
 250};
 251
 252/**
 253 *      tty_ldisc_ref_wait      -       wait for the tty ldisc
 254 *      @tty: tty device
 255 *
 256 *      Dereference the line discipline for the terminal and take a
 257 *      reference to it. If the line discipline is in flux then
 258 *      wait patiently until it changes.
 259 *
 260 *      Returns: NULL if the tty has been hungup and not re-opened with
 261 *               a new file descriptor, otherwise valid ldisc reference
 262 *
 263 *      Note: Must not be called from an IRQ/timer context. The caller
 264 *      must also be careful not to hold other locks that will deadlock
 265 *      against a discipline change, such as an existing ldisc reference
 266 *      (which we check for)
 267 *
 268 *      Note: a file_operations routine (read/poll/write) should use this
 269 *      function to wait for any ldisc lifetime events to finish.
 270 */
 271
 272struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
 273{
 274        ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
 275        if (!tty->ldisc)
 276                ldsem_up_read(&tty->ldisc_sem);
 277        return tty->ldisc;
 278}
 279EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
 280
 281/**
 282 *      tty_ldisc_ref           -       get the tty ldisc
 283 *      @tty: tty device
 284 *
 285 *      Dereference the line discipline for the terminal and take a
 286 *      reference to it. If the line discipline is in flux then
 287 *      return NULL. Can be called from IRQ and timer functions.
 288 */
 289
 290struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
 291{
 292        struct tty_ldisc *ld = NULL;
 293
 294        if (ldsem_down_read_trylock(&tty->ldisc_sem)) {
 295                ld = tty->ldisc;
 296                if (!ld)
 297                        ldsem_up_read(&tty->ldisc_sem);
 298        }
 299        return ld;
 300}
 301EXPORT_SYMBOL_GPL(tty_ldisc_ref);
 302
 303/**
 304 *      tty_ldisc_deref         -       free a tty ldisc reference
 305 *      @ld: reference to free up
 306 *
 307 *      Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
 308 *      be called in IRQ context.
 309 */
 310
 311void tty_ldisc_deref(struct tty_ldisc *ld)
 312{
 313        ldsem_up_read(&ld->tty->ldisc_sem);
 314}
 315EXPORT_SYMBOL_GPL(tty_ldisc_deref);
 316
 317
 318static inline int
 319__tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
 320{
 321        return ldsem_down_write(&tty->ldisc_sem, timeout);
 322}
 323
 324static inline int
 325__tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout)
 326{
 327        return ldsem_down_write_nested(&tty->ldisc_sem,
 328                                       LDISC_SEM_OTHER, timeout);
 329}
 330
 331static inline void __tty_ldisc_unlock(struct tty_struct *tty)
 332{
 333        ldsem_up_write(&tty->ldisc_sem);
 334}
 335
 336static int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
 337{
 338        int ret;
 339
 340        ret = __tty_ldisc_lock(tty, timeout);
 341        if (!ret)
 342                return -EBUSY;
 343        set_bit(TTY_LDISC_HALTED, &tty->flags);
 344        return 0;
 345}
 346
 347static void tty_ldisc_unlock(struct tty_struct *tty)
 348{
 349        clear_bit(TTY_LDISC_HALTED, &tty->flags);
 350        __tty_ldisc_unlock(tty);
 351}
 352
 353static int
 354tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2,
 355                            unsigned long timeout)
 356{
 357        int ret;
 358
 359        if (tty < tty2) {
 360                ret = __tty_ldisc_lock(tty, timeout);
 361                if (ret) {
 362                        ret = __tty_ldisc_lock_nested(tty2, timeout);
 363                        if (!ret)
 364                                __tty_ldisc_unlock(tty);
 365                }
 366        } else {
 367                /* if this is possible, it has lots of implications */
 368                WARN_ON_ONCE(tty == tty2);
 369                if (tty2 && tty != tty2) {
 370                        ret = __tty_ldisc_lock(tty2, timeout);
 371                        if (ret) {
 372                                ret = __tty_ldisc_lock_nested(tty, timeout);
 373                                if (!ret)
 374                                        __tty_ldisc_unlock(tty2);
 375                        }
 376                } else
 377                        ret = __tty_ldisc_lock(tty, timeout);
 378        }
 379
 380        if (!ret)
 381                return -EBUSY;
 382
 383        set_bit(TTY_LDISC_HALTED, &tty->flags);
 384        if (tty2)
 385                set_bit(TTY_LDISC_HALTED, &tty2->flags);
 386        return 0;
 387}
 388
 389static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2)
 390{
 391        tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT);
 392}
 393
 394static void tty_ldisc_unlock_pair(struct tty_struct *tty,
 395                                  struct tty_struct *tty2)
 396{
 397        __tty_ldisc_unlock(tty);
 398        if (tty2)
 399                __tty_ldisc_unlock(tty2);
 400}
 401
 402/**
 403 *      tty_ldisc_flush -       flush line discipline queue
 404 *      @tty: tty
 405 *
 406 *      Flush the line discipline queue (if any) and the tty flip buffers
 407 *      for this tty.
 408 */
 409
 410void tty_ldisc_flush(struct tty_struct *tty)
 411{
 412        struct tty_ldisc *ld = tty_ldisc_ref(tty);
 413
 414        tty_buffer_flush(tty, ld);
 415        if (ld)
 416                tty_ldisc_deref(ld);
 417}
 418EXPORT_SYMBOL_GPL(tty_ldisc_flush);
 419
 420/**
 421 *      tty_set_termios_ldisc           -       set ldisc field
 422 *      @tty: tty structure
 423 *      @disc: line discipline number
 424 *
 425 *      This is probably overkill for real world processors but
 426 *      they are not on hot paths so a little discipline won't do
 427 *      any harm.
 428 *
 429 *      The line discipline-related tty_struct fields are reset to
 430 *      prevent the ldisc driver from re-using stale information for
 431 *      the new ldisc instance.
 432 *
 433 *      Locking: takes termios_rwsem
 434 */
 435
 436static void tty_set_termios_ldisc(struct tty_struct *tty, int disc)
 437{
 438        down_write(&tty->termios_rwsem);
 439        tty->termios.c_line = disc;
 440        up_write(&tty->termios_rwsem);
 441
 442        tty->disc_data = NULL;
 443        tty->receive_room = 0;
 444}
 445
 446/**
 447 *      tty_ldisc_open          -       open a line discipline
 448 *      @tty: tty we are opening the ldisc on
 449 *      @ld: discipline to open
 450 *
 451 *      A helper opening method. Also a convenient debugging and check
 452 *      point.
 453 *
 454 *      Locking: always called with BTM already held.
 455 */
 456
 457static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
 458{
 459        WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
 460        if (ld->ops->open) {
 461                int ret;
 462                /* BTM here locks versus a hangup event */
 463                ret = ld->ops->open(tty);
 464                if (ret)
 465                        clear_bit(TTY_LDISC_OPEN, &tty->flags);
 466
 467                tty_ldisc_debug(tty, "%p: opened\n", ld);
 468                return ret;
 469        }
 470        return 0;
 471}
 472
 473/**
 474 *      tty_ldisc_close         -       close a line discipline
 475 *      @tty: tty we are opening the ldisc on
 476 *      @ld: discipline to close
 477 *
 478 *      A helper close method. Also a convenient debugging and check
 479 *      point.
 480 */
 481
 482static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
 483{
 484        WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
 485        clear_bit(TTY_LDISC_OPEN, &tty->flags);
 486        if (ld->ops->close)
 487                ld->ops->close(tty);
 488        tty_ldisc_debug(tty, "%p: closed\n", ld);
 489}
 490
 491/**
 492 *      tty_ldisc_restore       -       helper for tty ldisc change
 493 *      @tty: tty to recover
 494 *      @old: previous ldisc
 495 *
 496 *      Restore the previous line discipline or N_TTY when a line discipline
 497 *      change fails due to an open error
 498 */
 499
 500static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
 501{
 502        struct tty_ldisc *new_ldisc;
 503        int r;
 504
 505        /* There is an outstanding reference here so this is safe */
 506        old = tty_ldisc_get(tty, old->ops->num);
 507        WARN_ON(IS_ERR(old));
 508        tty->ldisc = old;
 509        tty_set_termios_ldisc(tty, old->ops->num);
 510        if (tty_ldisc_open(tty, old) < 0) {
 511                tty_ldisc_put(old);
 512                /* This driver is always present */
 513                new_ldisc = tty_ldisc_get(tty, N_TTY);
 514                if (IS_ERR(new_ldisc))
 515                        panic("n_tty: get");
 516                tty->ldisc = new_ldisc;
 517                tty_set_termios_ldisc(tty, N_TTY);
 518                r = tty_ldisc_open(tty, new_ldisc);
 519                if (r < 0)
 520                        panic("Couldn't open N_TTY ldisc for "
 521                              "%s --- error %d.",
 522                              tty_name(tty), r);
 523        }
 524}
 525
 526/**
 527 *      tty_set_ldisc           -       set line discipline
 528 *      @tty: the terminal to set
 529 *      @ldisc: the line discipline
 530 *
 531 *      Set the discipline of a tty line. Must be called from a process
 532 *      context. The ldisc change logic has to protect itself against any
 533 *      overlapping ldisc change (including on the other end of pty pairs),
 534 *      the close of one side of a tty/pty pair, and eventually hangup.
 535 */
 536
 537int tty_set_ldisc(struct tty_struct *tty, int disc)
 538{
 539        int retval;
 540        struct tty_ldisc *old_ldisc, *new_ldisc;
 541
 542        new_ldisc = tty_ldisc_get(tty, disc);
 543        if (IS_ERR(new_ldisc))
 544                return PTR_ERR(new_ldisc);
 545
 546        tty_lock(tty);
 547        retval = tty_ldisc_lock(tty, 5 * HZ);
 548        if (retval)
 549                goto err;
 550
 551        if (!tty->ldisc) {
 552                retval = -EIO;
 553                goto out;
 554        }
 555
 556        /* Check the no-op case */
 557        if (tty->ldisc->ops->num == disc)
 558                goto out;
 559
 560        if (test_bit(TTY_HUPPED, &tty->flags)) {
 561                /* We were raced by hangup */
 562                retval = -EIO;
 563                goto out;
 564        }
 565
 566        old_ldisc = tty->ldisc;
 567
 568        /* Shutdown the old discipline. */
 569        tty_ldisc_close(tty, old_ldisc);
 570
 571        /* Now set up the new line discipline. */
 572        tty->ldisc = new_ldisc;
 573        tty_set_termios_ldisc(tty, disc);
 574
 575        retval = tty_ldisc_open(tty, new_ldisc);
 576        if (retval < 0) {
 577                /* Back to the old one or N_TTY if we can't */
 578                tty_ldisc_put(new_ldisc);
 579                tty_ldisc_restore(tty, old_ldisc);
 580        }
 581
 582        if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
 583                down_read(&tty->termios_rwsem);
 584                tty->ops->set_ldisc(tty);
 585                up_read(&tty->termios_rwsem);
 586        }
 587
 588        /* At this point we hold a reference to the new ldisc and a
 589           reference to the old ldisc, or we hold two references to
 590           the old ldisc (if it was restored as part of error cleanup
 591           above). In either case, releasing a single reference from
 592           the old ldisc is correct. */
 593        new_ldisc = old_ldisc;
 594out:
 595        tty_ldisc_unlock(tty);
 596
 597        /* Restart the work queue in case no characters kick it off. Safe if
 598           already running */
 599        tty_buffer_restart_work(tty->port);
 600err:
 601        tty_ldisc_put(new_ldisc);       /* drop the extra reference */
 602        tty_unlock(tty);
 603        return retval;
 604}
 605
 606/**
 607 *      tty_ldisc_kill  -       teardown ldisc
 608 *      @tty: tty being released
 609 *
 610 *      Perform final close of the ldisc and reset tty->ldisc
 611 */
 612static void tty_ldisc_kill(struct tty_struct *tty)
 613{
 614        if (!tty->ldisc)
 615                return;
 616        /*
 617         * Now kill off the ldisc
 618         */
 619        tty_ldisc_close(tty, tty->ldisc);
 620        tty_ldisc_put(tty->ldisc);
 621        /* Force an oops if we mess this up */
 622        tty->ldisc = NULL;
 623}
 624
 625/**
 626 *      tty_reset_termios       -       reset terminal state
 627 *      @tty: tty to reset
 628 *
 629 *      Restore a terminal to the driver default state.
 630 */
 631
 632static void tty_reset_termios(struct tty_struct *tty)
 633{
 634        down_write(&tty->termios_rwsem);
 635        tty->termios = tty->driver->init_termios;
 636        tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
 637        tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
 638        up_write(&tty->termios_rwsem);
 639}
 640
 641
 642/**
 643 *      tty_ldisc_reinit        -       reinitialise the tty ldisc
 644 *      @tty: tty to reinit
 645 *      @disc: line discipline to reinitialize
 646 *
 647 *      Completely reinitialize the line discipline state, by closing the
 648 *      current instance, if there is one, and opening a new instance. If
 649 *      an error occurs opening the new non-N_TTY instance, the instance
 650 *      is dropped and tty->ldisc reset to NULL. The caller can then retry
 651 *      with N_TTY instead.
 652 *
 653 *      Returns 0 if successful, otherwise error code < 0
 654 */
 655
 656int tty_ldisc_reinit(struct tty_struct *tty, int disc)
 657{
 658        struct tty_ldisc *ld;
 659        int retval;
 660
 661        ld = tty_ldisc_get(tty, disc);
 662        if (IS_ERR(ld)) {
 663                BUG_ON(disc == N_TTY);
 664                return PTR_ERR(ld);
 665        }
 666
 667        if (tty->ldisc) {
 668                tty_ldisc_close(tty, tty->ldisc);
 669                tty_ldisc_put(tty->ldisc);
 670        }
 671
 672        /* switch the line discipline */
 673        tty->ldisc = ld;
 674        tty_set_termios_ldisc(tty, disc);
 675        retval = tty_ldisc_open(tty, tty->ldisc);
 676        if (retval) {
 677                if (!WARN_ON(disc == N_TTY)) {
 678                        tty_ldisc_put(tty->ldisc);
 679                        tty->ldisc = NULL;
 680                }
 681        }
 682        return retval;
 683}
 684
 685/**
 686 *      tty_ldisc_hangup                -       hangup ldisc reset
 687 *      @tty: tty being hung up
 688 *
 689 *      Some tty devices reset their termios when they receive a hangup
 690 *      event. In that situation we must also switch back to N_TTY properly
 691 *      before we reset the termios data.
 692 *
 693 *      Locking: We can take the ldisc mutex as the rest of the code is
 694 *      careful to allow for this.
 695 *
 696 *      In the pty pair case this occurs in the close() path of the
 697 *      tty itself so we must be careful about locking rules.
 698 */
 699
 700void tty_ldisc_hangup(struct tty_struct *tty, bool reinit)
 701{
 702        struct tty_ldisc *ld;
 703
 704        tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
 705
 706        ld = tty_ldisc_ref(tty);
 707        if (ld != NULL) {
 708                if (ld->ops->flush_buffer)
 709                        ld->ops->flush_buffer(tty);
 710                tty_driver_flush_buffer(tty);
 711                if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
 712                    ld->ops->write_wakeup)
 713                        ld->ops->write_wakeup(tty);
 714                if (ld->ops->hangup)
 715                        ld->ops->hangup(tty);
 716                tty_ldisc_deref(ld);
 717        }
 718
 719        wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
 720        wake_up_interruptible_poll(&tty->read_wait, POLLIN);
 721
 722        /*
 723         * Shutdown the current line discipline, and reset it to
 724         * N_TTY if need be.
 725         *
 726         * Avoid racing set_ldisc or tty_ldisc_release
 727         */
 728        tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);
 729
 730        if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
 731                tty_reset_termios(tty);
 732
 733        if (tty->ldisc) {
 734                if (reinit) {
 735                        if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0)
 736                                tty_ldisc_reinit(tty, N_TTY);
 737                } else
 738                        tty_ldisc_kill(tty);
 739        }
 740        tty_ldisc_unlock(tty);
 741}
 742
 743/**
 744 *      tty_ldisc_setup                 -       open line discipline
 745 *      @tty: tty being shut down
 746 *      @o_tty: pair tty for pty/tty pairs
 747 *
 748 *      Called during the initial open of a tty/pty pair in order to set up the
 749 *      line disciplines and bind them to the tty. This has no locking issues
 750 *      as the device isn't yet active.
 751 */
 752
 753int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
 754{
 755        int retval = tty_ldisc_open(tty, tty->ldisc);
 756        if (retval)
 757                return retval;
 758
 759        if (o_tty) {
 760                retval = tty_ldisc_open(o_tty, o_tty->ldisc);
 761                if (retval) {
 762                        tty_ldisc_close(tty, tty->ldisc);
 763                        return retval;
 764                }
 765        }
 766        return 0;
 767}
 768
 769/**
 770 *      tty_ldisc_release               -       release line discipline
 771 *      @tty: tty being shut down (or one end of pty pair)
 772 *
 773 *      Called during the final close of a tty or a pty pair in order to shut
 774 *      down the line discpline layer. On exit, each tty's ldisc is NULL.
 775 */
 776
 777void tty_ldisc_release(struct tty_struct *tty)
 778{
 779        struct tty_struct *o_tty = tty->link;
 780
 781        /*
 782         * Shutdown this line discipline. As this is the final close,
 783         * it does not race with the set_ldisc code path.
 784         */
 785
 786        tty_ldisc_lock_pair(tty, o_tty);
 787        tty_ldisc_kill(tty);
 788        if (o_tty)
 789                tty_ldisc_kill(o_tty);
 790        tty_ldisc_unlock_pair(tty, o_tty);
 791
 792        /* And the memory resources remaining (buffers, termios) will be
 793           disposed of when the kref hits zero */
 794
 795        tty_ldisc_debug(tty, "released\n");
 796}
 797
 798/**
 799 *      tty_ldisc_init          -       ldisc setup for new tty
 800 *      @tty: tty being allocated
 801 *
 802 *      Set up the line discipline objects for a newly allocated tty. Note that
 803 *      the tty structure is not completely set up when this call is made.
 804 */
 805
 806void tty_ldisc_init(struct tty_struct *tty)
 807{
 808        struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
 809        if (IS_ERR(ld))
 810                panic("n_tty: init_tty");
 811        tty->ldisc = ld;
 812}
 813
 814/**
 815 *      tty_ldisc_deinit        -       ldisc cleanup for new tty
 816 *      @tty: tty that was allocated recently
 817 *
 818 *      The tty structure must not becompletely set up (tty_ldisc_setup) when
 819 *      this call is made.
 820 */
 821void tty_ldisc_deinit(struct tty_struct *tty)
 822{
 823        if (tty->ldisc)
 824                tty_ldisc_put(tty->ldisc);
 825        tty->ldisc = NULL;
 826}
 827