aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index db15f9ba7c0b..bc84e125c6bc 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1111,9 +1111,7 @@ void tty_write_message(struct tty_struct *tty, char *msg)
1111 * Locks the line discipline as required 1111 * Locks the line discipline as required
1112 * Writes to the tty driver are serialized by the atomic_write_lock 1112 * Writes to the tty driver are serialized by the atomic_write_lock
1113 * and are then processed in chunks to the device. The line discipline 1113 * and are then processed in chunks to the device. The line discipline
1114 * write method will not be involked in parallel for each device 1114 * write method will not be invoked in parallel for each device.
1115 * The line discipline write method is called under the big
1116 * kernel lock for historical reasons. New code should not rely on this.
1117 */ 1115 */
1118 1116
1119static ssize_t tty_write(struct file *file, const char __user *buf, 1117static ssize_t tty_write(struct file *file, const char __user *buf,
@@ -1213,7 +1211,7 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
1213 * be held until the 'fast-open' is also done. Will change once we 1211 * be held until the 'fast-open' is also done. Will change once we
1214 * have refcounting in the driver and per driver locking 1212 * have refcounting in the driver and per driver locking
1215 */ 1213 */
1216struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, 1214static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
1217 struct inode *inode, int idx) 1215 struct inode *inode, int idx)
1218{ 1216{
1219 struct tty_struct *tty; 1217 struct tty_struct *tty;
@@ -1819,8 +1817,10 @@ got_driver:
1819 /* check whether we're reopening an existing tty */ 1817 /* check whether we're reopening an existing tty */
1820 tty = tty_driver_lookup_tty(driver, inode, index); 1818 tty = tty_driver_lookup_tty(driver, inode, index);
1821 1819
1822 if (IS_ERR(tty)) 1820 if (IS_ERR(tty)) {
1821 mutex_unlock(&tty_mutex);
1823 return PTR_ERR(tty); 1822 return PTR_ERR(tty);
1823 }
1824 } 1824 }
1825 1825
1826 if (tty) { 1826 if (tty) {
@@ -2050,7 +2050,6 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
2050/** 2050/**
2051 * tty_do_resize - resize event 2051 * tty_do_resize - resize event
2052 * @tty: tty being resized 2052 * @tty: tty being resized
2053 * @real_tty: real tty (not the same as tty if using a pty/tty pair)
2054 * @rows: rows (character) 2053 * @rows: rows (character)
2055 * @cols: cols (character) 2054 * @cols: cols (character)
2056 * 2055 *
@@ -2058,41 +2057,34 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
2058 * peform a terminal resize correctly 2057 * peform a terminal resize correctly
2059 */ 2058 */
2060 2059
2061int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, 2060int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
2062 struct winsize *ws)
2063{ 2061{
2064 struct pid *pgrp, *rpgrp; 2062 struct pid *pgrp;
2065 unsigned long flags; 2063 unsigned long flags;
2066 2064
2067 /* For a PTY we need to lock the tty side */ 2065 /* Lock the tty */
2068 mutex_lock(&real_tty->termios_mutex); 2066 mutex_lock(&tty->termios_mutex);
2069 if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) 2067 if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
2070 goto done; 2068 goto done;
2071 /* Get the PID values and reference them so we can 2069 /* Get the PID values and reference them so we can
2072 avoid holding the tty ctrl lock while sending signals */ 2070 avoid holding the tty ctrl lock while sending signals */
2073 spin_lock_irqsave(&tty->ctrl_lock, flags); 2071 spin_lock_irqsave(&tty->ctrl_lock, flags);
2074 pgrp = get_pid(tty->pgrp); 2072 pgrp = get_pid(tty->pgrp);
2075 rpgrp = get_pid(real_tty->pgrp);
2076 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 2073 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2077 2074
2078 if (pgrp) 2075 if (pgrp)
2079 kill_pgrp(pgrp, SIGWINCH, 1); 2076 kill_pgrp(pgrp, SIGWINCH, 1);
2080 if (rpgrp != pgrp && rpgrp)
2081 kill_pgrp(rpgrp, SIGWINCH, 1);
2082
2083 put_pid(pgrp); 2077 put_pid(pgrp);
2084 put_pid(rpgrp);
2085 2078
2086 tty->winsize = *ws; 2079 tty->winsize = *ws;
2087 real_tty->winsize = *ws;
2088done: 2080done:
2089 mutex_unlock(&real_tty->termios_mutex); 2081 mutex_unlock(&tty->termios_mutex);
2090 return 0; 2082 return 0;
2091} 2083}
2092 2084
2093/** 2085/**
2094 * tiocswinsz - implement window size set ioctl 2086 * tiocswinsz - implement window size set ioctl
2095 * @tty; tty 2087 * @tty; tty side of tty
2096 * @arg: user buffer for result 2088 * @arg: user buffer for result
2097 * 2089 *
2098 * Copies the user idea of the window size to the kernel. Traditionally 2090 * Copies the user idea of the window size to the kernel. Traditionally
@@ -2105,17 +2097,16 @@ done:
2105 * then calls into the default method. 2097 * then calls into the default method.
2106 */ 2098 */
2107 2099
2108static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, 2100static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
2109 struct winsize __user *arg)
2110{ 2101{
2111 struct winsize tmp_ws; 2102 struct winsize tmp_ws;
2112 if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) 2103 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2113 return -EFAULT; 2104 return -EFAULT;
2114 2105
2115 if (tty->ops->resize) 2106 if (tty->ops->resize)
2116 return tty->ops->resize(tty, real_tty, &tmp_ws); 2107 return tty->ops->resize(tty, &tmp_ws);
2117 else 2108 else
2118 return tty_do_resize(tty, real_tty, &tmp_ws); 2109 return tty_do_resize(tty, &tmp_ws);
2119} 2110}
2120 2111
2121/** 2112/**
@@ -2540,7 +2531,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2540 case TIOCGWINSZ: 2531 case TIOCGWINSZ:
2541 return tiocgwinsz(real_tty, p); 2532 return tiocgwinsz(real_tty, p);
2542 case TIOCSWINSZ: 2533 case TIOCSWINSZ:
2543 return tiocswinsz(tty, real_tty, p); 2534 return tiocswinsz(real_tty, p);
2544 case TIOCCONS: 2535 case TIOCCONS:
2545 return real_tty != tty ? -EINVAL : tioccons(file); 2536 return real_tty != tty ? -EINVAL : tioccons(file);
2546 case FIONBIO: 2537 case FIONBIO:
@@ -2785,6 +2776,8 @@ void initialize_tty_struct(struct tty_struct *tty,
2785 INIT_WORK(&tty->hangup_work, do_tty_hangup); 2776 INIT_WORK(&tty->hangup_work, do_tty_hangup);
2786 mutex_init(&tty->atomic_read_lock); 2777 mutex_init(&tty->atomic_read_lock);
2787 mutex_init(&tty->atomic_write_lock); 2778 mutex_init(&tty->atomic_write_lock);
2779 mutex_init(&tty->output_lock);
2780 mutex_init(&tty->echo_lock);
2788 spin_lock_init(&tty->read_lock); 2781 spin_lock_init(&tty->read_lock);
2789 spin_lock_init(&tty->ctrl_lock); 2782 spin_lock_init(&tty->ctrl_lock);
2790 INIT_LIST_HEAD(&tty->tty_files); 2783 INIT_LIST_HEAD(&tty->tty_files);