aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/n_tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r--drivers/tty/n_tty.c81
1 files changed, 37 insertions, 44 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 26f097f60b10..d2b496750d59 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -321,7 +321,8 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
321 321
322static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) 322static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
323{ 323{
324 *read_buf_addr(ldata, ldata->read_head++) = c; 324 *read_buf_addr(ldata, ldata->read_head) = c;
325 ldata->read_head++;
325} 326}
326 327
327/** 328/**
@@ -351,13 +352,13 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
351{ 352{
352 unsigned long flags; 353 unsigned long flags;
353 354
354 spin_lock_irqsave(&tty->ctrl_lock, flags);
355 if (tty->link->packet) { 355 if (tty->link->packet) {
356 spin_lock_irqsave(&tty->ctrl_lock, flags);
356 tty->ctrl_status |= TIOCPKT_FLUSHREAD; 357 tty->ctrl_status |= TIOCPKT_FLUSHREAD;
358 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
357 if (waitqueue_active(&tty->link->read_wait)) 359 if (waitqueue_active(&tty->link->read_wait))
358 wake_up_interruptible(&tty->link->read_wait); 360 wake_up_interruptible(&tty->link->read_wait);
359 } 361 }
360 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
361} 362}
362 363
363/** 364/**
@@ -2128,7 +2129,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2128 int minimum, time; 2129 int minimum, time;
2129 ssize_t retval = 0; 2130 ssize_t retval = 0;
2130 long timeout; 2131 long timeout;
2131 unsigned long flags;
2132 int packet; 2132 int packet;
2133 2133
2134 c = job_control(tty, file); 2134 c = job_control(tty, file);
@@ -2174,10 +2174,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2174 unsigned char cs; 2174 unsigned char cs;
2175 if (b != buf) 2175 if (b != buf)
2176 break; 2176 break;
2177 spin_lock_irqsave(&tty->link->ctrl_lock, flags); 2177 spin_lock_irq(&tty->link->ctrl_lock);
2178 cs = tty->link->ctrl_status; 2178 cs = tty->link->ctrl_status;
2179 tty->link->ctrl_status = 0; 2179 tty->link->ctrl_status = 0;
2180 spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); 2180 spin_unlock_irq(&tty->link->ctrl_lock);
2181 if (tty_put_user(tty, cs, b++)) { 2181 if (tty_put_user(tty, cs, b++)) {
2182 retval = -EFAULT; 2182 retval = -EFAULT;
2183 b--; 2183 b--;
@@ -2193,45 +2193,29 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2193 2193
2194 if (!input_available_p(tty, 0)) { 2194 if (!input_available_p(tty, 0)) {
2195 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { 2195 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
2196 up_read(&tty->termios_rwsem); 2196 retval = -EIO;
2197 tty_flush_to_ldisc(tty); 2197 break;
2198 down_read(&tty->termios_rwsem);
2199 if (!input_available_p(tty, 0)) {
2200 retval = -EIO;
2201 break;
2202 }
2203 } else {
2204 if (tty_hung_up_p(file))
2205 break;
2206 if (!timeout)
2207 break;
2208 if (file->f_flags & O_NONBLOCK) {
2209 retval = -EAGAIN;
2210 break;
2211 }
2212 if (signal_pending(current)) {
2213 retval = -ERESTARTSYS;
2214 break;
2215 }
2216 n_tty_set_room(tty);
2217 up_read(&tty->termios_rwsem);
2218
2219 timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
2220 timeout);
2221
2222 down_read(&tty->termios_rwsem);
2223 continue;
2224 } 2198 }
2225 } 2199 if (tty_hung_up_p(file))
2226 2200 break;
2227 /* Deal with packet mode. */ 2201 if (!timeout)
2228 if (packet && b == buf) { 2202 break;
2229 if (tty_put_user(tty, TIOCPKT_DATA, b++)) { 2203 if (file->f_flags & O_NONBLOCK) {
2230 retval = -EFAULT; 2204 retval = -EAGAIN;
2231 b--;
2232 break; 2205 break;
2233 } 2206 }
2234 nr--; 2207 if (signal_pending(current)) {
2208 retval = -ERESTARTSYS;
2209 break;
2210 }
2211 n_tty_set_room(tty);
2212 up_read(&tty->termios_rwsem);
2213
2214 timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
2215 timeout);
2216
2217 down_read(&tty->termios_rwsem);
2218 continue;
2235 } 2219 }
2236 2220
2237 if (ldata->icanon && !L_EXTPROC(tty)) { 2221 if (ldata->icanon && !L_EXTPROC(tty)) {
@@ -2243,8 +2227,17 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2243 break; 2227 break;
2244 } else { 2228 } else {
2245 int uncopied; 2229 int uncopied;
2246 /* The copy function takes the read lock and handles 2230
2247 locking internally for this case */ 2231 /* Deal with packet mode. */
2232 if (packet && b == buf) {
2233 if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
2234 retval = -EFAULT;
2235 b--;
2236 break;
2237 }
2238 nr--;
2239 }
2240
2248 uncopied = copy_from_read_buf(tty, &b, &nr); 2241 uncopied = copy_from_read_buf(tty, &b, &nr);
2249 uncopied += copy_from_read_buf(tty, &b, &nr); 2242 uncopied += copy_from_read_buf(tty, &b, &nr);
2250 if (uncopied) { 2243 if (uncopied) {