summaryrefslogtreecommitdiff
path: root/nuttx/drivers/serial.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-19 18:43:50 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-19 18:43:50 +0000
commitd8c1d769c45dde09573ea6ba3f968491cc5e68b2 (patch)
tree6a6105e2401ec7e9eb4e590c49c3121b2c4b82ae /nuttx/drivers/serial.c
parentb62fb5c894ea28ccc83c5760605f5322bf38f971 (diff)
downloadpx4-nuttx-d8c1d769c45dde09573ea6ba3f968491cc5e68b2.tar.gz
px4-nuttx-d8c1d769c45dde09573ea6ba3f968491cc5e68b2.tar.bz2
px4-nuttx-d8c1d769c45dde09573ea6ba3f968491cc5e68b2.zip
Move poll save area back into struct pollfd (as it was
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1288 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/serial.c')
-rw-r--r--nuttx/drivers/serial.c80
1 files changed, 50 insertions, 30 deletions
diff --git a/nuttx/drivers/serial.c b/nuttx/drivers/serial.c
index 4e409fa06..ddc7338bc 100644
--- a/nuttx/drivers/serial.c
+++ b/nuttx/drivers/serial.c
@@ -79,7 +79,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
#ifndef CONFIG_DISABLE_POLL
-static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds);
+static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup);
#endif
/************************************************************************************
@@ -400,58 +400,57 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
****************************************************************************/
#ifndef CONFIG_DISABLE_POLL
-int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
+int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup)
{
FAR struct inode *inode = filep->f_inode;
FAR uart_dev_t *dev = inode->i_private;
pollevent_t eventset;
int ndx;
+ int ret = OK;
int i;
/* Some sanity checking */
+
#if CONFIG_DEBUG
- if (!dev)
+ if (!dev || !fds)
{
return -ENODEV;
}
#endif
- /* Find an available slot for the poll structure reference */
+ /* Are we setting up the poll? Or tearing it down? */
uart_takesem(&dev->pollsem);
- for (i = 0; i < CONFIG_DEV_CONSOLE_NPOLLWAITERS; i++)
+ if (setup)
{
- /* Find the slot with the value equal to filep->f_priv. If there
- * is no previously installed poll structure, then f_priv will
- * be NULL and we will find the first unused slot. If f_priv is
- * is non-NULL, then we will find the slot that was used for the
- * previous setup.
+ /* This is a request to set up the poll. Find an available
+ * slot for the poll structure reference
*/
- if (dev->fds[i] == filep->f_priv)
+ for (i = 0; i < CONFIG_DEV_CONSOLE_NPOLLWAITERS; i++)
{
- dev->fds[i] = fds;
- break;
- }
- }
-
- if (i >= CONFIG_DEV_CONSOLE_NPOLLWAITERS)
- {
- DEBUGASSERT(fds != NULL);
- return -EBUSY;
- }
+ /* Find an available slot */
- /* Set or clear the poll event structure reference in the 'struct file'
- * private data.
- */
+ if (!dev->fds[i])
+ {
+ /* Bind the poll structure and this slot */
- filep->f_priv = fds;
+ dev->fds[i] = fds;
+ fds->private = &dev->fds[i];
+ break;
+ }
+ }
- /* Check if we should immediately notify on any of the requested events */
+ if (i >= CONFIG_DEV_CONSOLE_NPOLLWAITERS)
+ {
+ fds->private = NULL;
+ ret = -EBUSY;
+ goto errout;
+ }
- if (fds)
- {
- /* Check if the xmit buffer is full. */
+ /* Should immediately notify on any of the requested events?
+ * First, check if the xmit buffer is full.
+ */
eventset = 0;
@@ -480,10 +479,31 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
{
uart_pollnotify(dev, eventset);
}
+
+ }
+ else if (fds->private)
+ {
+ /* This is a request to tear down the poll. */
+
+ struct pollfd **slot = (struct pollfd **)fds->private;
+
+#ifdef CONFIG_DEBUG
+ if (!slot)
+ {
+ ret = -EIO;
+ goto errout;
+ }
+#endif
+
+ /* Remove all memory of the poll setup */
+
+ *slot = NULL;
+ fds->private = NULL;
}
+errout:
uart_givesem(&dev->pollsem);
- return OK;
+ return ret;
}
#endif