1
0
Fork 0
forked from nuttx/nuttx-update

Fixe open count error + O_NONBLOCK function

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1013 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2008-10-09 19:20:02 +00:00
parent 175c69a462
commit fed5871039
3 changed files with 47 additions and 14 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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;