diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 61 |
1 files changed, 38 insertions, 23 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 936a4ead6c2..6556f7452ba 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -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) && @@ -2134,7 +2135,7 @@ done: * actually has driver level meaning and triggers a VC resize. * * Locking: - * Driver dependant. The default do_resize method takes the + * Driver dependent. The default do_resize method takes the * tty termios mutex and ctrl_lock. The console takes its own lock * then calls into the default method. */ @@ -2155,7 +2156,7 @@ static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) * tioccons - allow admin to move logical console * @file: the file to become console * - * Allow the adminstrator to move the redirected console device + * Allow the administrator to move the redirected console device * * Locking: uses redirect_lock to guard the redirect information */ @@ -2290,7 +2291,7 @@ EXPORT_SYMBOL_GPL(tty_get_pgrp); /** * tiocgpgrp - get process group * @tty: tty passed by user - * @real_tty: tty side of the tty pased by the user if a pty else the tty + * @real_tty: tty side of the tty passed by the user if a pty else the tty * @p: returned pid * * Obtain the process group of the tty. If there is no process group @@ -2367,7 +2368,7 @@ out_unlock: /** * tiocgsid - get session id * @tty: tty passed by user - * @real_tty: tty side of the tty pased by the user if a pty else the tty + * @real_tty: tty side of the tty passed by the user if a pty else the tty * @p: pointer to returned session id * * Obtain the session id of the tty. If there is no session @@ -2888,6 +2889,20 @@ void initialize_tty_struct(struct tty_struct *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 * @ch: character |