tty: Implement a drain delay in the tty port
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Thu, 11 Jun 2009 11:25:25 +0000 (12:25 +0100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jun 2009 15:50:56 +0000 (08:50 -0700)
We need this for devices that cannot flush and wait, but which do not order
data and modem events. Without it we will hang up before all the data
clears the hardware. Needed for the USB changes.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/char/tty_port.c
include/linux/tty.h

index 926d4a5593fac0f0d1c4033252efe32e23564a7a..4d08b6d27c28b5f81589367c9d810bc33c53bd36 100644 (file)
@@ -308,6 +308,17 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
        if (port->flags & ASYNC_INITIALIZED &&
                        port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
                tty_wait_until_sent(tty, port->closing_wait);
+       if (port->drain_delay) {
+               unsigned int bps = tty_get_baud_rate(tty);
+               long timeout;
+
+               if (bps > 1200)
+                       timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
+                                                               HZ / 10);
+               else
+                       timeout = 2 * HZ;
+               schedule_timeout_interruptible(timeout);
+       }
        return 1;
 }
 EXPORT_SYMBOL(tty_port_close_start);
index 98694364c96fdef164b4e790a5eb58e42a2e7497..bed5a3d4030743d10fb4d28e4e93314e87a09722 100644 (file)
@@ -201,6 +201,9 @@ struct tty_port {
        unsigned char           *xmit_buf;      /* Optional buffer */
        int                     close_delay;    /* Close port delay */
        int                     closing_wait;   /* Delay for output */
+       int                     drain_delay;    /* Set to zero if no pure time
+                                                  based drain is needed else
+                                                  set to size of fifo */
 };
 
 /*