summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-11-08 18:17:00 (GMT)
committerDan Williams <dcbw@redhat.com>2012-11-14 17:03:56 (GMT)
commite798b6e663131aaabc8919de2a46eb2f58d43aa0 (patch)
tree0f1e49af0afdb48bd1ec4afc61ead12e15b12a0a
parent191eabe952031b5dcc86e92c993d6bfbef101f3f (diff)
serial: fix warning when driver doesn't support closing_wait (bgo #630670)
It appears that GIOChannel might also do some flushing, so make sure our warning captures that delay if there is one. Also be paranoid and make sure nothing reset our closing_wait value.
-rw-r--r--src/mm-serial-port.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
index 568f4e4..ce2dfeb 100644
--- a/src/mm-serial-port.c
+++ b/src/mm-serial-port.c
@@ -902,7 +902,7 @@ mm_serial_port_open (MMSerialPort *self, GError **error)
/* Don't wait for pending data when closing the port; this can cause some
* stupid devices that don't respond to URBs on a particular port to hang
- * for 30 seconds when probin fails.
+ * for 30 seconds when probing fails. See GNOME bug #630670.
*/
if (ioctl (priv->fd, TIOCGSERIAL, &sinfo) == 0) {
sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE;
@@ -980,11 +980,25 @@ mm_serial_port_close (MMSerialPort *self)
if (priv->fd >= 0) {
GTimeVal tv_start, tv_end;
+ struct serial_struct sinfo;
mm_info ("(%s) closing serial port...", device);
mm_port_set_connected (MM_PORT (self), FALSE);
+ /* Paranoid: ensure our closing_wait value is still set so we ignore
+ * pending data when closing the port. See GNOME bug #630670.
+ */
+ if (ioctl (priv->fd, TIOCGSERIAL, &sinfo) == 0) {
+ if (sinfo.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ mm_warn ("(%s): serial port closing_wait was reset!", device);
+ sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE;
+ (void) ioctl (priv->fd, TIOCSSERIAL, &sinfo);
+ }
+ }
+
+ g_get_current_time (&tv_start);
+
if (priv->channel) {
g_source_remove (priv->watch_id);
priv->watch_id = 0;
@@ -993,8 +1007,6 @@ mm_serial_port_close (MMSerialPort *self)
priv->channel = NULL;
}
- g_get_current_time (&tv_start);
-
tcsetattr (priv->fd, TCSANOW, &priv->old_t);
tcflush (priv->fd, TCIOFLUSH);
close (priv->fd);