diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d7d50b48287e..6556f7452ba6 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/tty_io.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | */ | 3 | */ |
6 | 4 | ||
@@ -964,12 +962,14 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
964 | } | 962 | } |
965 | 963 | ||
966 | void tty_write_unlock(struct tty_struct *tty) | 964 | void tty_write_unlock(struct tty_struct *tty) |
965 | __releases(&tty->atomic_write_lock) | ||
967 | { | 966 | { |
968 | mutex_unlock(&tty->atomic_write_lock); | 967 | mutex_unlock(&tty->atomic_write_lock); |
969 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); | 968 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
970 | } | 969 | } |
971 | 970 | ||
972 | int tty_write_lock(struct tty_struct *tty, int ndelay) | 971 | int tty_write_lock(struct tty_struct *tty, int ndelay) |
972 | __acquires(&tty->atomic_write_lock) | ||
973 | { | 973 | { |
974 | if (!mutex_trylock(&tty->atomic_write_lock)) { | 974 | if (!mutex_trylock(&tty->atomic_write_lock)) { |
975 | if (ndelay) | 975 | if (ndelay) |
@@ -1391,16 +1391,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1391 | return ERR_PTR(-ENODEV); | 1391 | return ERR_PTR(-ENODEV); |
1392 | 1392 | ||
1393 | tty = alloc_tty_struct(); | 1393 | tty = alloc_tty_struct(); |
1394 | if (!tty) | 1394 | if (!tty) { |
1395 | goto fail_no_mem; | 1395 | retval = -ENOMEM; |
1396 | goto err_module_put; | ||
1397 | } | ||
1396 | initialize_tty_struct(tty, driver, idx); | 1398 | initialize_tty_struct(tty, driver, idx); |
1397 | 1399 | ||
1398 | retval = tty_driver_install_tty(driver, tty); | 1400 | retval = tty_driver_install_tty(driver, tty); |
1399 | if (retval < 0) { | 1401 | if (retval < 0) |
1400 | free_tty_struct(tty); | 1402 | goto err_deinit_tty; |
1401 | module_put(driver->owner); | ||
1402 | return ERR_PTR(retval); | ||
1403 | } | ||
1404 | 1403 | ||
1405 | /* | 1404 | /* |
1406 | * Structures all installed ... call the ldisc open routines. | 1405 | * Structures all installed ... call the ldisc open routines. |
@@ -1409,15 +1408,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1409 | */ | 1408 | */ |
1410 | retval = tty_ldisc_setup(tty, tty->link); | 1409 | retval = tty_ldisc_setup(tty, tty->link); |
1411 | if (retval) | 1410 | if (retval) |
1412 | goto release_mem_out; | 1411 | goto err_release_tty; |
1413 | return tty; | 1412 | return tty; |
1414 | 1413 | ||
1415 | fail_no_mem: | 1414 | err_deinit_tty: |
1415 | deinitialize_tty_struct(tty); | ||
1416 | free_tty_struct(tty); | ||
1417 | err_module_put: | ||
1416 | module_put(driver->owner); | 1418 | module_put(driver->owner); |
1417 | return ERR_PTR(-ENOMEM); | 1419 | return ERR_PTR(retval); |
1418 | 1420 | ||
1419 | /* call the tty release_tty routine to clean out this slot */ | 1421 | /* call the tty release_tty routine to clean out this slot */ |
1420 | release_mem_out: | 1422 | err_release_tty: |
1421 | if (printk_ratelimit()) | 1423 | if (printk_ratelimit()) |
1422 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " | 1424 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1423 | "clearing slot %d\n", idx); | 1425 | "clearing slot %d\n", idx); |
@@ -1892,6 +1894,7 @@ got_driver: | |||
1892 | retval = tty_add_file(tty, filp); | 1894 | retval = tty_add_file(tty, filp); |
1893 | if (retval) { | 1895 | if (retval) { |
1894 | tty_unlock(); | 1896 | tty_unlock(); |
1897 | tty_release(inode, filp); | ||
1895 | return retval; | 1898 | return retval; |
1896 | } | 1899 | } |
1897 | 1900 | ||
@@ -1902,12 +1905,10 @@ got_driver: | |||
1902 | #ifdef TTY_DEBUG_HANGUP | 1905 | #ifdef TTY_DEBUG_HANGUP |
1903 | printk(KERN_DEBUG "opening %s...", tty->name); | 1906 | printk(KERN_DEBUG "opening %s...", tty->name); |
1904 | #endif | 1907 | #endif |
1905 | if (!retval) { | 1908 | if (tty->ops->open) |
1906 | if (tty->ops->open) | 1909 | retval = tty->ops->open(tty, filp); |
1907 | retval = tty->ops->open(tty, filp); | 1910 | else |
1908 | else | 1911 | retval = -ENODEV; |
1909 | retval = -ENODEV; | ||
1910 | } | ||
1911 | filp->f_flags = saved_flags; | 1912 | filp->f_flags = saved_flags; |
1912 | 1913 | ||
1913 | if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && | 1914 | if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && |
@@ -2888,6 +2889,20 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2888 | } | 2889 | } |
2889 | 2890 | ||
2890 | /** | 2891 | /** |
2892 | * deinitialize_tty_struct | ||
2893 | * @tty: tty to deinitialize | ||
2894 | * | ||
2895 | * This subroutine deinitializes a tty structure that has been newly | ||
2896 | * allocated but tty_release cannot be called on that yet. | ||
2897 | * | ||
2898 | * Locking: none - tty in question must not be exposed at this point | ||
2899 | */ | ||
2900 | void deinitialize_tty_struct(struct tty_struct *tty) | ||
2901 | { | ||
2902 | tty_ldisc_deinit(tty); | ||
2903 | } | ||
2904 | |||
2905 | /** | ||
2891 | * tty_put_char - write one character to a tty | 2906 | * tty_put_char - write one character to a tty |
2892 | * @tty: tty | 2907 | * @tty: tty |
2893 | * @ch: character | 2908 | * @ch: character |