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