summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/ChangeLog1
-rw-r--r--nuttx/Documentation/NuttX.html3
-rw-r--r--nuttx/drivers/serial.c57
3 files changed, 47 insertions, 14 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index b1589b13a..181967a05 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -491,6 +491,7 @@
* Add LPC214x USB serial configuration; Add examples/usbserial test (still a work in progress)
* Added USB device side driver for the DM320 (untested at initial checkin)
* Fixed an error in a previous (post 0.3.15) check-in that broke the LPC214x system timer.
+ * Fixed serial drive bugs related to (1) open counts and (2) recognizing O_NONBLOCK on read.
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index e9376d5a3..09f2b465c 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
- <p>Last Updated: October 7, 2008</p>
+ <p>Last Updated: October 9, 2008</p>
</td>
</tr>
</table>
@@ -1081,6 +1081,7 @@ nuttx-0.3.16 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* Add LPC214x USB serial configuration; Add examples/usbserial test (still a work in progress)
* Added USB device side driver for the DM320 (untested at initial checkin)
* Fixed an error in a previous (post 0.3.15) check-in that broke the LPC214x system timer.
+ * Fixed serial drive bugs related to (1) open counts and (2) recognizing O_NONBLOCK on read.
pascal-0.1.3 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
diff --git a/nuttx/drivers/serial.c b/nuttx/drivers/serial.c
index 3d0536604..bd4ca33e7 100644
--- a/nuttx/drivers/serial.c
+++ b/nuttx/drivers/serial.c
@@ -38,12 +38,15 @@
************************************************************************************/
#include <nuttx/config.h>
+
#include <sys/types.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
+#include <fcntl.h>
#include <errno.h>
#include <debug.h>
+
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/fs.h>
@@ -254,7 +257,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
{
FAR struct inode *inode = filep->f_inode;
FAR uart_dev_t *dev = inode->i_private;
- ssize_t ret = buflen;
+ ssize_t recvd = 0;
/* Only one user can be accessing dev->recv.tail at once */
@@ -266,22 +269,50 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
*/
uart_disablerxint(dev);
- while (buflen)
+ while (recvd < buflen)
{
+ /* Check if there is more data to return in the circular buffer */
+
if (dev->recv.head != dev->recv.tail)
{
*buffer++ = dev->recv.buffer[dev->recv.tail];
- buflen--;
+ recvd++;
if (++(dev->recv.tail) >= dev->recv.size)
{
dev->recv.tail = 0;
}
}
+
+ /* No... then we would have to wait to get receive more data.
+ * If the user has specified the O_NONBLOCK option, then do not
+ * return what we have.
+ */
+
+ else if (filep->f_oflags & O_NONBLOCK)
+ {
+ /* If nothing was transferred, then return the -EAGAIN
+ * error (not zero which means end of file).
+ */
+
+ if (recvd < 1)
+ {
+ recvd = -EAGAIN;
+ }
+
+ /* Break out of the loop and return the number of bytes
+ * received up to the wait condition.
+ */
+
+ break;
+ }
+
+ /* Otherwise we are going to wait */
+
else
{
/* Wait for some characters to be sent from the buffer
- * with the TX interrupt disabled.
+ * with the TX interrupt re-enabled.
*/
dev->recvwaiting = TRUE;
@@ -293,7 +324,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
uart_enablerxint(dev);
uart_givesem(&dev->recv.sem);
- return ret;
+ return recvd;
}
/************************************************************************************
@@ -421,7 +452,8 @@ static int uart_open(FAR struct file *filep)
ret = uart_setup(dev);
if (ret < 0)
{
- goto errout_with_irqsdisabled;
+ irqrestore(flags);
+ goto errout_with_sem;
}
}
@@ -435,7 +467,8 @@ static int uart_open(FAR struct file *filep)
if (ret < 0)
{
uart_shutdown(dev);
- goto errout_with_irqsdisabled;
+ irqrestore(flags);
+ goto errout_with_sem;
}
/* Mark the io buffers empty */
@@ -448,15 +481,13 @@ static int uart_open(FAR struct file *filep)
/* Enable the RX interrupt */
uart_enablerxint(dev);
-
- /* Save the new open count on success */
-
- dev->open_count = tmp;
-
-errout_with_irqsdisabled:
irqrestore(flags);
}
+ /* Save the new open count on success */
+
+ dev->open_count = tmp;
+
errout_with_sem:
uart_givesem(&dev->closesem);
return ret;