diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 48569035da56..c9d8a138b84c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2429,6 +2429,7 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) /** * send_break - performed time break + * @file: file object * @tty: device to break on * @duration: timeout in mS * @@ -2438,7 +2439,7 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) * Locking: * @tty->atomic_write_lock serializes */ -static int send_break(struct tty_struct *tty, unsigned int duration) +static int send_break(struct file *file, struct tty_struct *tty, unsigned int duration) { int retval; @@ -2455,7 +2456,10 @@ static int send_break(struct tty_struct *tty, unsigned int duration) retval = tty->ops->break_ctl(tty, -1); if (!retval) { msleep_interruptible(duration); - retval = tty->ops->break_ctl(tty, 0); + if (tty_hung_up_p(file)) + retval = -EIO; + else + retval = tty->ops->break_ctl(tty, 0); } else if (retval == -EOPNOTSUPP) { /* some drivers can tell only dynamically */ retval = 0; @@ -2727,10 +2731,10 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) * This is used by the tcdrain() termios function. */ if (!arg) - return send_break(tty, 250); + return send_break(file, tty, 250); return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ - return send_break(tty, arg ? arg*100 : 250); + return send_break(file, tty, arg ? arg * 100 : 250); case TIOCMGET: return tty_tiocmget(tty, p);