changeset 852:7f6b818846b4

Fix problems with -EAGAIN. Change behaviour of VMIN to match accepted behaviour.
author gthomas
date Thu, 20 Mar 2003 19:03:03 +0000
parents b42d82dbafed
children 3131db84b89c
files packages/io/serial/current/ChangeLog packages/io/serial/current/src/common/serial.c packages/io/serial/current/src/common/termiostty.c
diffstat 3 files changed, 29 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/packages/io/serial/current/ChangeLog
+++ b/packages/io/serial/current/ChangeLog
@@ -1,3 +1,13 @@
+2003-03-20  Gary Thomas  <gary@mlbassoc.com>
+
+	* src/common/serial.c: Only return -EAGAIN if no data moved.
+
+2003-03-11  Gary Thomas  <gary@mlbassoc.com>
+
+	* src/common/termiostty.c (termios_read): VMIN handling still wasn't
+	quite correct.  When VMIN > 0, at least VMIN characters should be
+	read.
+
 2003-02-24  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* cdl/io_serial.cdl: Fix doc link.
--- a/packages/io/serial/current/src/common/serial.c
+++ b/packages/io/serial/current/src/common/serial.c
@@ -9,6 +9,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -343,7 +344,7 @@ serial_write(cyg_io_handle_t handle, con
                     if (!cbuf->blocking) {
                         *len -= size;   // number of characters actually sent
                         cbuf->waiting = false;
-                        res = -EAGAIN;
+                        res = size == 0 ? -EAGAIN : ENOERROR;
                         break;
                     }
 #endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
@@ -440,7 +441,7 @@ serial_read(cyg_io_handle_t handle, void
 #ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
                 if (!cbuf->blocking) {
                     *len = size;        // characters actually read
-                    res = -EAGAIN;
+                    res = size == 0 ? -EAGAIN : ENOERROR;
                     break;
                 }
 #endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
--- a/packages/io/serial/current/src/common/termiostty.c
+++ b/packages/io/serial/current/src/common/termiostty.c
@@ -10,6 +10,7 @@
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 // Copyright (C) 2003 Jonathan Larmour
+// Copyright (C) 2003 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -661,7 +662,14 @@ termios_read(cyg_io_handle_t handle, voi
                                  CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
                                  &dev_buf_conf, &dbc_len );
         CYG_ASSERT( res == ENOERR, "Query buffer status failed!" );
-        *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
+        if (dev_buf_conf.rx_count > 0) {
+            // Adjust length to be max characters currently available
+            *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
+        } else if (t->c_cc[VMIN] == 0) {
+            // No chars available - don't block
+            *len = 0;
+            return ENOERR;
+        }
     } // if
 
     while (!returnnow && size < *len) {
@@ -754,10 +762,7 @@ termios_read(cyg_io_handle_t handle, voi
                     c = '\r';
                 returnnow = true; // FIXME: true even for INLCR?
             } // else if
-        } else { // non-canonical mode
-            if ( t->c_cc[ VMIN ] && (size+1 >= t->c_cc[ VMIN ]) )
-                returnnow = true;
-        } // else
+        } // if 
 
 #ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
         if ( (t->c_lflag & ISIG) && (t->c_cc[ VINTR ] == c) ) {
@@ -792,6 +797,12 @@ termios_read(cyg_io_handle_t handle, voi
                 termios_write( handle, &c, &clen );
             }
         }
+
+        if ( (t->c_lflag & ICANON) == 0 ) {
+            // Check to see if read has been satisfied
+            if ( t->c_cc[ VMIN ] && (size >= t->c_cc[ VMIN ]) )
+                returnnow = true;
+        }
         cyg_drv_mutex_unlock( &priv->lock );
     } // while