]> Pileus Git - ~andy/linux/blobdiff - drivers/tty/tty_io.c
Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6
[~andy/linux] / drivers / tty / tty_io.c
index d7d50b48287e8a7374e4d2e814527b4faa9dfaa9..6556f7452ba6f960a9f083068f1674164c93ff11 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/tty_io.c
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
@@ -964,12 +962,14 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
 }
 
 void tty_write_unlock(struct tty_struct *tty)
+       __releases(&tty->atomic_write_lock)
 {
        mutex_unlock(&tty->atomic_write_lock);
        wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
 }
 
 int tty_write_lock(struct tty_struct *tty, int ndelay)
+       __acquires(&tty->atomic_write_lock)
 {
        if (!mutex_trylock(&tty->atomic_write_lock)) {
                if (ndelay)
@@ -1391,16 +1391,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
                return ERR_PTR(-ENODEV);
 
        tty = alloc_tty_struct();
-       if (!tty)
-               goto fail_no_mem;
+       if (!tty) {
+               retval = -ENOMEM;
+               goto err_module_put;
+       }
        initialize_tty_struct(tty, driver, idx);
 
        retval = tty_driver_install_tty(driver, tty);
-       if (retval < 0) {
-               free_tty_struct(tty);
-               module_put(driver->owner);
-               return ERR_PTR(retval);
-       }
+       if (retval < 0)
+               goto err_deinit_tty;
 
        /*
         * Structures all installed ... call the ldisc open routines.
@@ -1409,15 +1408,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
         */
        retval = tty_ldisc_setup(tty, tty->link);
        if (retval)
-               goto release_mem_out;
+               goto err_release_tty;
        return tty;
 
-fail_no_mem:
+err_deinit_tty:
+       deinitialize_tty_struct(tty);
+       free_tty_struct(tty);
+err_module_put:
        module_put(driver->owner);
-       return ERR_PTR(-ENOMEM);
+       return ERR_PTR(retval);
 
        /* call the tty release_tty routine to clean out this slot */
-release_mem_out:
+err_release_tty:
        if (printk_ratelimit())
                printk(KERN_INFO "tty_init_dev: ldisc open failed, "
                                 "clearing slot %d\n", idx);
@@ -1892,6 +1894,7 @@ got_driver:
        retval = tty_add_file(tty, filp);
        if (retval) {
                tty_unlock();
+               tty_release(inode, filp);
                return retval;
        }
 
@@ -1902,12 +1905,10 @@ got_driver:
 #ifdef TTY_DEBUG_HANGUP
        printk(KERN_DEBUG "opening %s...", tty->name);
 #endif
-       if (!retval) {
-               if (tty->ops->open)
-                       retval = tty->ops->open(tty, filp);
-               else
-                       retval = -ENODEV;
-       }
+       if (tty->ops->open)
+               retval = tty->ops->open(tty, filp);
+       else
+               retval = -ENODEV;
        filp->f_flags = saved_flags;
 
        if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
@@ -2887,6 +2888,20 @@ void initialize_tty_struct(struct tty_struct *tty,
        tty->dev = tty_get_device(tty);
 }
 
+/**
+ *     deinitialize_tty_struct
+ *     @tty: tty to deinitialize
+ *
+ *     This subroutine deinitializes a tty structure that has been newly
+ *     allocated but tty_release cannot be called on that yet.
+ *
+ *     Locking: none - tty in question must not be exposed at this point
+ */
+void deinitialize_tty_struct(struct tty_struct *tty)
+{
+       tty_ldisc_deinit(tty);
+}
+
 /**
  *     tty_put_char    -       write one character to a tty
  *     @tty: tty