summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2017-03-02 04:23:53 +0000
committerian <ian@FreeBSD.org>2017-03-02 04:23:53 +0000
commit441c0c0ed529fc9fb17e0feb520d123e21acb7f5 (patch)
tree798f99c36b3f220290c85d5b78d50866d47b5875 /lib
parenta8e4be5c56fa510af7512ec8fc2bfe5dc41ffe45 (diff)
downloadFreeBSD-src-441c0c0ed529fc9fb17e0feb520d123e21acb7f5.zip
FreeBSD-src-441c0c0ed529fc9fb17e0feb520d123e21acb7f5.tar.gz
MFC r311954, r311996, r312077, r312080:
Rework tty_drain() to poll the hardware for completion, and restore drain timeout handling to historical freebsd behavior. The primary reason for these changes is the need to have tty_drain() call ttydevsw_busy() at some reasonable sub-second rate, to poll hardware that doesn't signal an interrupt when the transmit shift register becomes empty (which includes virtually all USB serial hardware). Such hardware hangs in a ttyout wait, because it never gets an opportunity to trigger a wakeup from the sleep in tty_drain() by calling ttydisc_getc() again, after handing the last of the buffered data to the hardware. Restructure the tty_drain loop so that device-busy is checked one more time after tty_timedwait() returns an error only if the error is EWOULDBLOCK; other errors cause an immediate return. This fixes the case of the tty disappearing while in tty_drain(). Check tty_gone() after allocating IO buffers. The tty lock has to be dropped then reacquired due to using M_WAITOK, which opens a window in which the tty device can disappear. Check for this and return ENXIO back up the call chain so that callers can cope. Correct the comments about how much buffer is allocated.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/tcsendbreak.333
1 files changed, 30 insertions, 3 deletions
diff --git a/lib/libc/gen/tcsendbreak.3 b/lib/libc/gen/tcsendbreak.3
index a7e86d0..dd43a29 100644
--- a/lib/libc/gen/tcsendbreak.3
+++ b/lib/libc/gen/tcsendbreak.3
@@ -28,7 +28,7 @@
.\" @(#)tcsendbreak.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd January 11, 2017
.Dt TCSENDBREAK 3
.Os
.Sh NAME
@@ -137,17 +137,44 @@ is not a terminal.
A signal interrupted the
.Fn tcdrain
function.
+.It Bq Er EWOULDBLOCK
+The configured timeout expired before the
+.Fn tcdrain
+function could write all buffered output.
.El
.Sh SEE ALSO
.Xr tcsetattr 3 ,
-.Xr termios 4
+.Xr termios 4 ,
+.Xr tty 4 ,
+.Xr comcontrol 8
.Sh STANDARDS
The
.Fn tcsendbreak ,
-.Fn tcdrain ,
.Fn tcflush
and
.Fn tcflow
functions are expected to be compliant with the
.St -p1003.1-88
specification.
+.Pp
+The
+.Fn tcdrain
+function is expected to be compliant with
+.St -p1003.1-88
+when the drain wait value is set to zero with
+.Xr comcontrol 8 ,
+or with
+.Xr ioctl 2
+.Va TIOCSDRAINWAIT ,
+or with
+.Xr sysctl 8
+.Va kern.tty_drainwait .
+A non-zero drain wait value can result in
+.Fn tcdrain
+returning
+.Va EWOULDBLOCK
+without writing all output.
+The default value for
+.Va kern.tty_drainwait
+is 300 seconds.
+
OpenPOWER on IntegriCloud