diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-11-19 18:43:50 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-11-19 18:43:50 +0000 |
commit | d8c1d769c45dde09573ea6ba3f968491cc5e68b2 (patch) | |
tree | 6a6105e2401ec7e9eb4e590c49c3121b2c4b82ae /nuttx/drivers/serial.c | |
parent | b62fb5c894ea28ccc83c5760605f5322bf38f971 (diff) | |
download | px4-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.c | 80 |
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 |