crypto: ansi_cprng - Fix module initialization
[safe/jmp/linux-2.6] / drivers / char / tty_ldisc.c
index a58a19a..a19e935 100644 (file)
@@ -126,7 +126,7 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
        struct tty_ldisc *ld;
        struct tty_ldisc_ops *ldops;
        int err = -EINVAL;
-       
+
        ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
        if (ld == NULL)
                return ERR_PTR(-ENOMEM);
@@ -148,8 +148,10 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
                }
        }
        spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       if (err)
+       if (err) {
+               kfree(ld);
                return ERR_PTR(err);
+       }
        return ld;
 }
 
@@ -205,15 +207,16 @@ static void tty_ldisc_put(struct tty_ldisc *ld)
        ldo->refcount--;
        module_put(ldo->owner);
        spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       WARN_ON(ld->refcount);
        kfree(ld);
 }
 
-static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
+static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
 {
        return (*pos < NR_LDISCS) ? pos : NULL;
 }
 
-static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
+static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
 {
        (*pos)++;
        return (*pos < NR_LDISCS) ? pos : NULL;
@@ -227,7 +230,7 @@ static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
 {
        int i = *(loff_t *)v;
        struct tty_ldisc *ld;
-       
+
        ld = tty_ldisc_try_get(i);
        if (IS_ERR(ld))
                return 0;
@@ -262,7 +265,7 @@ const struct file_operations tty_ldiscs_proc_fops = {
  *     @ld: line discipline
  *
  *     Install an instance of a line discipline into a tty structure. The
- *     ldisc must have a reference count above zero to ensure it remains/
+ *     ldisc must have a reference count above zero to ensure it remains.
  *     The tty instance refcount starts at zero.
  *
  *     Locking:
@@ -325,7 +328,6 @@ struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
        WARN_ON(tty->ldisc->refcount == 0);
        return tty->ldisc;
 }
-
 EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
 
 /**
@@ -345,7 +347,6 @@ struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
                return tty->ldisc;
        return NULL;
 }
-
 EXPORT_SYMBOL_GPL(tty_ldisc_ref);
 
 /**
@@ -373,7 +374,6 @@ void tty_ldisc_deref(struct tty_ldisc *ld)
                wake_up(&tty_ldisc_wait);
        spin_unlock_irqrestore(&tty_ldisc_lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(tty_ldisc_deref);
 
 /**
@@ -396,6 +396,26 @@ void tty_ldisc_enable(struct tty_struct *tty)
 }
 
 /**
+ *     tty_ldisc_flush -       flush line discipline queue
+ *     @tty: tty
+ *
+ *     Flush the line discipline queue (if any) for this tty. If there
+ *     is no line discipline active this is a no-op.
+ */
+
+void tty_ldisc_flush(struct tty_struct *tty)
+{
+       struct tty_ldisc *ld = tty_ldisc_ref(tty);
+       if (ld) {
+               if (ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               tty_ldisc_deref(ld);
+       }
+       tty_buffer_flush(tty);
+}
+EXPORT_SYMBOL_GPL(tty_ldisc_flush);
+
+/**
  *     tty_set_termios_ldisc           -       set ldisc field
  *     @tty: tty structure
  *     @num: line discipline number
@@ -471,7 +491,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
        if (tty_ldisc_open(tty, old) < 0) {
                tty_ldisc_put(old);
                /* This driver is always present */
-               new_ldisc =tty_ldisc_get(N_TTY);
+               new_ldisc = tty_ldisc_get(N_TTY);
                if (IS_ERR(new_ldisc))
                        panic("n_tty: get");
                tty_ldisc_assign(tty, new_ldisc);
@@ -493,7 +513,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
  *     be obtained while the delayed work queue halt ensures that no more
  *     data is fed to the ldisc.
  *
- *     In order to wait for any existing references to complete see 
+ *     In order to wait for any existing references to complete see
  *     tty_ldisc_wait_idle.
  */
 
@@ -590,7 +610,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
                mutex_lock(&tty->ldisc_mutex);
        }
        set_bit(TTY_LDISC_CHANGING, &tty->flags);
-               
+
        /*
         *      No more input please, we are switching. The new ldisc
         *      will update this value in the ldisc open function
@@ -774,6 +794,8 @@ void tty_ldisc_hangup(struct tty_struct *tty)
                /* Avoid racing set_ldisc */
                mutex_lock(&tty->ldisc_mutex);
                /* Switch back to N_TTY */
+               tty_ldisc_halt(tty);
+               tty_ldisc_wait_idle(tty);
                tty_ldisc_reinit(tty);
                /* At this point we have a closed ldisc and we want to
                   reopen it. We could defer this to the next open but
@@ -820,8 +842,8 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
  *     @tty: tty being shut down
  *     @o_tty: pair tty for pty/tty pairs
  *
- *     Called during the final close of a tty/pty pair in order to shut down the
- *     line discpline layer. On exit the ldisc assigned is N_TTY and the
+ *     Called during the final close of a tty/pty pair in order to shut down
+ *     the line discpline layer. On exit the ldisc assigned is N_TTY and the
  *     ldisc has not been opened.
  */