diff options
Diffstat (limited to 'nuttx/drivers/pipes')
-rw-r--r-- | nuttx/drivers/pipes/Kconfig | 4 | ||||
-rw-r--r-- | nuttx/drivers/pipes/Make.defs | 46 | ||||
-rw-r--r-- | nuttx/drivers/pipes/fifo.c | 139 | ||||
-rw-r--r-- | nuttx/drivers/pipes/pipe.c | 286 | ||||
-rw-r--r-- | nuttx/drivers/pipes/pipe_common.c | 682 | ||||
-rw-r--r-- | nuttx/drivers/pipes/pipe_common.h | 139 |
6 files changed, 0 insertions, 1296 deletions
diff --git a/nuttx/drivers/pipes/Kconfig b/nuttx/drivers/pipes/Kconfig deleted file mode 100644 index ae2bf3130..000000000 --- a/nuttx/drivers/pipes/Kconfig +++ /dev/null @@ -1,4 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# diff --git a/nuttx/drivers/pipes/Make.defs b/nuttx/drivers/pipes/Make.defs deleted file mode 100644 index 836505481..000000000 --- a/nuttx/drivers/pipes/Make.defs +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################ -# drivers/pipes/Make.defs -# -# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt <gnutt@nuttx.org> -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) - -# Include pipe driver - -CSRCS += pipe.c fifo.c pipe_common.c - -# Include pipe build support - -DEPPATH += --dep-path pipes -VPATH += :pipes -endif diff --git a/nuttx/drivers/pipes/fifo.c b/nuttx/drivers/pipes/fifo.c deleted file mode 100644 index 03aafd0f0..000000000 --- a/nuttx/drivers/pipes/fifo.c +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** - * drivers/pipes/fifo.c - * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <nuttx/fs/fs.h> -#include <errno.h> - -#include "pipe_common.h" - -#if CONFIG_DEV_PIPE_SIZE > 0 - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const struct file_operations fifo_fops = -{ - pipecommon_open, /* open */ - pipecommon_close, /* close */ - pipecommon_read, /* read */ - pipecommon_write, /* write */ - 0, /* seek */ - 0 /* ioctl */ -#ifndef CONFIG_DISABLE_POLL - , pipecommon_poll /* poll */ -#endif -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: mkfifo - * - * Description: - * mkfifo() makes a FIFO device driver file with name 'pathname.' Unlike - * Linux, a NuttX FIFO is not a special file type but simply a device driver - * instance. 'mode' specifies the FIFO's permissions. - * - * Once the FIFO has been created by mkfifo(), any thread can open it for - * reading or writing, in the same way as an ordinary file. However, it must - * have been opened from both reading and writing before input or output - * can be performed. This FIFO implementation will block all attempts to - * open a FIFO read-only until at least one thread has opened the FIFO for - * writing. - * - * If all threads that write to the FIFO have closed, subsequent calls to - * read() on the FIFO will return 0 (end-of-file). - * - * Inputs: - * pathname - The full path to the FIFO instance to attach to or to create - * (if not already created). - * mode - Ignored for now - * - * Return: - * 0 is returned on success; otherwise, -1 is returned with errno set - * appropriately. - * - ****************************************************************************/ - -int mkfifo(FAR const char *pathname, mode_t mode) -{ - struct pipe_dev_s *dev; - int ret; - - /* Allocate and initialize a new device structure instance */ - - dev = pipecommon_allocdev(); - if (!dev) - { - return -ENOMEM; - } - - ret = register_driver(pathname, &fifo_fops, mode, (void*)dev); - if (ret != 0) - { - pipecommon_freedev(dev); - } - - return ret; -} - -#endif /* CONFIG_DEV_PIPE_SIZE > 0 */ diff --git a/nuttx/drivers/pipes/pipe.c b/nuttx/drivers/pipes/pipe.c deleted file mode 100644 index 20c160475..000000000 --- a/nuttx/drivers/pipes/pipe.c +++ /dev/null @@ -1,286 +0,0 @@ -/**************************************************************************** - * drivers/pipes/pipe.c - * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Compilation Switches - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <nuttx/fs/fs.h> -#include <stdio.h> -#include <unistd.h> -#include <semaphore.h> -#include <fcntl.h> -#include <errno.h> - -#include "pipe_common.h" - -#if CONFIG_DEV_PIPE_SIZE > 0 - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -#define MAX_PIPES 32 - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static int pipe_close(FAR struct file *filep); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const struct file_operations pipe_fops = -{ - pipecommon_open, /* open */ - pipe_close, /* close */ - pipecommon_read, /* read */ - pipecommon_write, /* write */ - 0, /* seek */ - 0 /* ioctl */ -#ifndef CONFIG_DISABLE_POLL - , pipecommon_poll /* poll */ -#endif -}; - -static sem_t g_pipesem = { 1 }; -static uint32_t g_pipeset = 0; -static uint32_t g_pipecreated = 0; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pipe_allocate - ****************************************************************************/ - -static inline int pipe_allocate(void) -{ - int pipeno; - int ret = -ENFILE; - - for (pipeno = 0; pipeno < MAX_PIPES; pipeno++) - { - if ((g_pipeset & (1 << pipeno)) == 0) - { - g_pipeset |= (1 << pipeno); - ret = pipeno; - break; - } - } - - return ret; -} - -/**************************************************************************** - * Name: pipe_free - ****************************************************************************/ - -static inline void pipe_free(int pipeno) -{ - int ret = sem_wait(&g_pipesem); - if (ret == 0) - { - g_pipeset &= ~(1 << pipeno); - (void)sem_post(&g_pipesem); - } -} - -/**************************************************************************** - * Name: pipe_close - ****************************************************************************/ - -static int pipe_close(FAR struct file *filep) -{ - struct inode *inode = filep->f_inode; - struct pipe_dev_s *dev = inode->i_private; - int ret; - - /* Some sanity checking */ -#if CONFIG_DEBUG - if (!dev) - { - return -EBADF; - } -#endif - - /* Perform common close operations */ - - ret = pipecommon_close(filep); - if (ret == 0 && dev->d_refs == 0) - { - /* Release the pipe when there are no further open references to it. */ - - pipe_free(dev->d_pipeno); - } - - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pipe - * - * Description: - * pipe() creates a pair of file descriptors, pointing to a pipe inode, and - * places them in the array pointed to by 'filedes'. filedes[0] is for reading, - * filedes[1] is for writing. - * - * Inputs: - * filedes[2] - The user provided array in which to catch the pipe file - * descriptors - * - * Return: - * 0 is returned on success; otherwise, -1 is returned with errno set - * appropriately. - * - ****************************************************************************/ - -int pipe(int filedes[2]) -{ - struct pipe_dev_s *dev = NULL; - char devname[16]; - int pipeno; - int err; - int ret; - - /* Get exclusive access to the pipe allocation data */ - - ret = sem_wait(&g_pipesem); - if (ret < 0) - { - /* sem_wait() will have already set errno */ - - return ERROR; - } - - /* Allocate a minor number for the pipe device */ - - pipeno = pipe_allocate(); - if (pipeno < 0) - { - (void)sem_post(&g_pipesem); - err = -pipeno; - goto errout; - } - - /* Create a pathname to the pipe device */ - - sprintf(devname, "/dev/pipe%d", pipeno); - - /* Check if the pipe device has already been created */ - - if ((g_pipecreated & (1 << pipeno)) == 0) - { - /* No.. Allocate and initialize a new device structure instance */ - - dev = pipecommon_allocdev(); - if (!dev) - { - (void)sem_post(&g_pipesem); - err = ENOMEM; - goto errout_with_pipe; - } - - dev->d_pipeno = pipeno; - - /* Register the pipe device */ - - ret = register_driver(devname, &pipe_fops, 0666, (void*)dev); - if (ret != 0) - { - (void)sem_post(&g_pipesem); - err = -ret; - goto errout_with_dev; - } - - /* Remember that we created this device */ - - g_pipecreated |= (1 << pipeno); - } - - (void)sem_post(&g_pipesem); - - /* Get a write file descriptor */ - - filedes[1] = open(devname, O_WRONLY); - if (filedes[1] < 0) - { - err = -filedes[1]; - goto errout_with_driver; - } - - /* Get a read file descriptor */ - - filedes[0] = open(devname, O_RDONLY); - if (filedes[0] < 0) - { - err = -filedes[0]; - goto errout_with_wrfd; - } - - return OK; - -errout_with_wrfd: - close(filedes[1]); -errout_with_driver: - unregister_driver(devname); -errout_with_dev: - pipecommon_freedev(dev); -errout_with_pipe: - pipe_free(pipeno); -errout: - errno = err; - return ERROR; -} - -#endif /* CONFIG_DEV_PIPE_SIZE > 0 */ diff --git a/nuttx/drivers/pipes/pipe_common.c b/nuttx/drivers/pipes/pipe_common.c deleted file mode 100644 index 5f61fdd8e..000000000 --- a/nuttx/drivers/pipes/pipe_common.c +++ /dev/null @@ -1,682 +0,0 @@ -/**************************************************************************** - * drivers/pipes/pipe_common.c - * - * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdint.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <sched.h> -#include <semaphore.h> -#include <fcntl.h> -#include <errno.h> -#include <assert.h> -#include <debug.h> - -#include <nuttx/kmalloc.h> -#include <nuttx/fs/fs.h> -#if CONFIG_DEBUG -# include <nuttx/arch.h> -#endif - -#include "pipe_common.h" - -#if CONFIG_DEV_PIPE_SIZE > 0 - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* CONFIG_DEV_PIPEDUMP will dump the contents of each transfer into and out - * of the pipe. - */ - -#ifdef CONFIG_DEV_PIPEDUMP -# define pipe_dumpbuffer(m,a,n) lib_dumpbuffer(m,a,n) -#else -# define pipe_dumpbuffer(m,a,n) -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static void pipecommon_semtake(sem_t *sem); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pipecommon_semtake - ****************************************************************************/ - -static void pipecommon_semtake(sem_t *sem) -{ - while (sem_wait(sem) != 0) - { - /* The only case that an error should occur here is if the wait was - * awakened by a signal. - */ - - ASSERT(errno == EINTR); - } -} - -/**************************************************************************** - * Name: pipecommon_pollnotify - ****************************************************************************/ - -#ifndef CONFIG_DISABLE_POLL -static void pipecommon_pollnotify(FAR struct pipe_dev_s *dev, pollevent_t eventset) -{ - int i; - - for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++) - { - struct pollfd *fds = dev->d_fds[i]; - if (fds) - { - fds->revents |= (fds->events & eventset); - if (fds->revents != 0) - { - fvdbg("Report events: %02x\n", fds->revents); - sem_post(fds->sem); - } - } - } -} -#else -# define pipecommon_pollnotify(dev,event) -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pipecommon_allocdev - ****************************************************************************/ - -FAR struct pipe_dev_s *pipecommon_allocdev(void) -{ - struct pipe_dev_s *dev; - - /* Allocate a private structure to manage the pipe */ - - dev = (struct pipe_dev_s *)kmalloc(sizeof(struct pipe_dev_s)); - if (dev) - { - /* Initialize the private structure */ - - memset(dev, 0, sizeof(struct pipe_dev_s)); - sem_init(&dev->d_bfsem, 0, 1); - sem_init(&dev->d_rdsem, 0, 0); - sem_init(&dev->d_wrsem, 0, 0); - } - - return dev; -} - -/**************************************************************************** - * Name: pipecommon_freedev - ****************************************************************************/ - -void pipecommon_freedev(FAR struct pipe_dev_s *dev) -{ - sem_destroy(&dev->d_bfsem); - sem_destroy(&dev->d_rdsem); - sem_destroy(&dev->d_wrsem); - kfree(dev); -} - -/**************************************************************************** - * Name: pipecommon_open - ****************************************************************************/ - -int pipecommon_open(FAR struct file *filep) -{ - struct inode *inode = filep->f_inode; - struct pipe_dev_s *dev = inode->i_private; - int sval; - int ret; - - /* Some sanity checking */ -#if CONFIG_DEBUG - if (!dev) - { - return -EBADF; - } -#endif - - /* Make sure that we have exclusive access to the device structure. The - * sem_wait() call should fail only if we are awakened by a signal. - */ - - ret = sem_wait(&dev->d_bfsem); - if (ret != OK) - { - fdbg("sem_wait failed: %d\n", errno); - DEBUGASSERT(errno > 0); - return -errno; - } - - /* If this the first reference on the device, then allocate the buffer */ - - if (dev->d_refs == 0) - { - dev->d_buffer = (uint8_t*)kmalloc(CONFIG_DEV_PIPE_SIZE); - if (!dev->d_buffer) - { - (void)sem_post(&dev->d_bfsem); - return -ENOMEM; - } - } - - /* Increment the reference count on the pipe instance */ - - dev->d_refs++; - - /* If opened for writing, increment the count of writers on on the pipe instance */ - - if ((filep->f_oflags & O_WROK) != 0) - { - dev->d_nwriters++; - - /* If this this is the first writer, then the read semaphore indicates the - * number of readers waiting for the first writer. Wake them all up. - */ - - if (dev->d_nwriters == 1) - { - while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0) - { - sem_post(&dev->d_rdsem); - } - } - } - - /* If opened for read-only, then wait for at least one writer on the pipe */ - - sched_lock(); - (void)sem_post(&dev->d_bfsem); - if ((filep->f_oflags & O_RDWR) == O_RDONLY && dev->d_nwriters < 1) - { - /* NOTE: d_rdsem is normally used when the read logic waits for more - * data to be written. But until the first writer has opened the - * pipe, the meaning is different: it is used prevent O_RDONLY open - * calls from returning until there is at least one writer on the pipe. - * This is required both by spec and also because it prevents - * subsequent read() calls from returning end-of-file because there is - * no writer on the pipe. - */ - - ret = sem_wait(&dev->d_rdsem); - if (ret != OK) - { - /* The sem_wait() call should fail only if we are awakened by - * a signal. - */ - - fdbg("sem_wait failed: %d\n", errno); - DEBUGASSERT(errno > 0); - ret = -errno; - - /* Immediately close the pipe that we just opened */ - - (void)pipecommon_close(filep); - } - } - - sched_unlock(); - return ret; -} - -/**************************************************************************** - * Name: pipecommon_close - ****************************************************************************/ - -int pipecommon_close(FAR struct file *filep) -{ - struct inode *inode = filep->f_inode; - struct pipe_dev_s *dev = inode->i_private; - int sval; - - /* Some sanity checking */ -#if CONFIG_DEBUG - if (!dev) - { - return -EBADF; - } -#endif - - /* Make sure that we have exclusive access to the device structure. - * NOTE: close() is supposed to return EINTR if interrupted, however - * I've never seen anyone check that. - */ - - pipecommon_semtake(&dev->d_bfsem); - - /* Check if the decremented reference count would go to zero */ - - if (dev->d_refs > 1) - { - /* No.. then just decrement the reference count */ - - dev->d_refs--; - - /* If opened for writing, decrement the count of writers on on the pipe instance */ - - if ((filep->f_oflags & O_WROK) != 0) - { - /* If there are no longer any writers on the pipe, then notify all of the - * waiting readers that they must return end-of-file. - */ - - if (--dev->d_nwriters <= 0) - { - while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0) - { - sem_post(&dev->d_rdsem); - } - } - } - } - else - { - /* Yes... deallocate the buffer */ - - kfree(dev->d_buffer); - dev->d_buffer = NULL; - - /* And reset all counts and indices */ - - dev->d_wrndx = 0; - dev->d_rdndx = 0; - dev->d_refs = 0; - dev->d_nwriters = 0; - } - - sem_post(&dev->d_bfsem); - return OK; -} - -/**************************************************************************** - * Name: pipecommon_read - ****************************************************************************/ - -ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len) -{ - struct inode *inode = filep->f_inode; - struct pipe_dev_s *dev = inode->i_private; -#ifdef CONFIG_DEV_PIPEDUMP - FAR uint8_t *start = (uint8_t*)buffer; -#endif - ssize_t nread = 0; - int sval; - int ret; - - /* Some sanity checking */ -#if CONFIG_DEBUG - if (!dev) - { - return -ENODEV; - } -#endif - - /* Make sure that we have exclusive access to the device structure */ - - if (sem_wait(&dev->d_bfsem) < 0) - { - return ERROR; - } - - /* If the pipe is empty, then wait for something to be written to it */ - - while (dev->d_wrndx == dev->d_rdndx) - { - /* If O_NONBLOCK was set, then return EGAIN */ - - if (filep->f_oflags & O_NONBLOCK) - { - sem_post(&dev->d_bfsem); - return -EAGAIN; - } - - /* If there are no writers on the pipe, then return end of file */ - - if (dev->d_nwriters <= 0) - { - sem_post(&dev->d_bfsem); - return 0; - } - - /* Otherwise, wait for something to be written to the pipe */ - - sched_lock(); - sem_post(&dev->d_bfsem); - ret = sem_wait(&dev->d_rdsem); - sched_unlock(); - - if (ret < 0 || sem_wait(&dev->d_bfsem) < 0) - { - return ERROR; - } - } - - /* Then return whatever is available in the pipe (which is at least one byte) */ - - nread = 0; - while (nread < len && dev->d_wrndx != dev->d_rdndx) - { - *buffer++ = dev->d_buffer[dev->d_rdndx]; - if (++dev->d_rdndx >= CONFIG_DEV_PIPE_SIZE) - { - dev->d_rdndx = 0; - } - nread++; - } - - /* Notify all waiting writers that bytes have been removed from the buffer */ - - while (sem_getvalue(&dev->d_wrsem, &sval) == 0 && sval < 0) - { - sem_post(&dev->d_wrsem); - } - - /* Notify all poll/select waiters that they can write to the FIFO */ - - pipecommon_pollnotify(dev, POLLOUT); - - sem_post(&dev->d_bfsem); - pipe_dumpbuffer("From PIPE:", start, nread); - return nread; -} - -/**************************************************************************** - * Name: pipecommon_write - ****************************************************************************/ - -ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t len) -{ - struct inode *inode = filep->f_inode; - struct pipe_dev_s *dev = inode->i_private; - ssize_t nwritten = 0; - ssize_t last; - int nxtwrndx; - int sval; - - /* Some sanity checking */ - -#if CONFIG_DEBUG - if (!dev) - { - return -ENODEV; - } -#endif - - pipe_dumpbuffer("To PIPE:", (uint8_t*)buffer, len); - - /* At present, this method cannot be called from interrupt handlers. That is - * because it calls sem_wait (via pipecommon_semtake below) and sem_wait cannot - * be called from interrupt level. This actually happens fairly commonly - * IF dbg() is called from interrupt handlers and stdout is being redirected - * via a pipe. In that case, the debug output will try to go out the pipe - * (interrupt handlers should use the lldbg() APIs). - * - * On the other hand, it would be very valuable to be able to feed the pipe - * from an interrupt handler! TODO: Consider disabling interrupts instead - * of taking semaphores so that pipes can be written from interupt handlers - */ - - DEBUGASSERT(up_interrupt_context() == false) - - /* Make sure that we have exclusive access to the device structure */ - - if (sem_wait(&dev->d_bfsem) < 0) - { - return ERROR; - } - - /* Loop until all of the bytes have been written */ - - last = 0; - for (;;) - { - /* Calculate the write index AFTER the next byte is written */ - - nxtwrndx = dev->d_wrndx + 1; - if (nxtwrndx >= CONFIG_DEV_PIPE_SIZE) - { - nxtwrndx = 0; - } - - /* Would the next write overflow the circular buffer? */ - - if (nxtwrndx != dev->d_rdndx) - { - /* No... copy the byte */ - - dev->d_buffer[dev->d_wrndx] = *buffer++; - dev->d_wrndx = nxtwrndx; - - /* Is the write complete? */ - - if (++nwritten >= len) - { - /* Yes.. Notify all of the waiting readers that more data is available */ - - while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0) - { - sem_post(&dev->d_rdsem); - } - - /* Notify all poll/select waiters that they can write to the FIFO */ - - pipecommon_pollnotify(dev, POLLIN); - - /* Return the number of bytes written */ - - sem_post(&dev->d_bfsem); - return len; - } - } - else - { - /* There is not enough room for the next byte. Was anything written in this pass? */ - - if (last < nwritten) - { - /* Yes.. Notify all of the waiting readers that more data is available */ - - while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0) - { - sem_post(&dev->d_rdsem); - } - } - last = nwritten; - - /* If O_NONBLOCK was set, then return partial bytes written or EGAIN */ - - if (filep->f_oflags & O_NONBLOCK) - { - if (nwritten == 0) - { - nwritten = -EAGAIN; - } - sem_post(&dev->d_bfsem); - return nwritten; - } - - /* There is more to be written.. wait for data to be removed from the pipe */ - - sched_lock(); - sem_post(&dev->d_bfsem); - pipecommon_semtake(&dev->d_wrsem); - sched_unlock(); - pipecommon_semtake(&dev->d_bfsem); - } - } -} - -/**************************************************************************** - * Name: pipecommon_poll - ****************************************************************************/ - -#ifndef CONFIG_DISABLE_POLL -int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup) -{ - FAR struct inode *inode = filep->f_inode; - FAR struct pipe_dev_s *dev = inode->i_private; - pollevent_t eventset; - pipe_ndx_t nbytes; - int ret = OK; - int i; - - /* Some sanity checking */ - -#if CONFIG_DEBUG - if (!dev || !fds) - { - return -ENODEV; - } -#endif - - /* Are we setting up the poll? Or tearing it down? */ - - pipecommon_semtake(&dev->d_bfsem); - if (setup) - { - /* This is a request to set up the poll. Find an available - * slot for the poll structure reference - */ - - for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++) - { - /* Find an available slot */ - - if (!dev->d_fds[i]) - { - /* Bind the poll structure and this slot */ - - dev->d_fds[i] = fds; - fds->priv = &dev->d_fds[i]; - break; - } - } - - if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS) - { - fds->priv = NULL; - ret = -EBUSY; - goto errout; - } - - /* Should immediately notify on any of the requested events? - * First, determine how many bytes are in the buffer - */ - - if (dev->d_wrndx >= dev->d_rdndx) - { - nbytes = dev->d_wrndx - dev->d_rdndx; - } - else - { - nbytes = (CONFIG_DEV_PIPE_SIZE-1) + dev->d_wrndx - dev->d_rdndx; - } - - /* Notify the POLLOUT event if the pipe is not full */ - - eventset = 0; - if (nbytes < (CONFIG_DEV_PIPE_SIZE-1)) - { - eventset |= POLLOUT; - } - - /* Notify the POLLIN event if the pipe is not empty */ - - if (nbytes > 0) - { - eventset |= POLLIN; - } - - if (eventset) - { - pipecommon_pollnotify(dev, eventset); - } - } - else - { - /* This is a request to tear down the poll. */ - - struct pollfd **slot = (struct pollfd **)fds->priv; - -#ifdef CONFIG_DEBUG - if (!slot) - { - ret = -EIO; - goto errout; - } -#endif - - /* Remove all memory of the poll setup */ - - *slot = NULL; - fds->priv = NULL; - } - -errout: - sem_post(&dev->d_bfsem); - return ret; -} -#endif - -#endif /* CONFIG_DEV_PIPE_SIZE > 0 */ diff --git a/nuttx/drivers/pipes/pipe_common.h b/nuttx/drivers/pipes/pipe_common.h deleted file mode 100644 index 44822e07f..000000000 --- a/nuttx/drivers/pipes/pipe_common.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** - * drivers/pipe/pipe_common.h - * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#ifndef __DRIVERS_PIPES_PIPE_COMMON_H -#define __DRIVERS_PIPES_PIPE_COMMON_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> -#include <sys/types.h> - -#include <stdint.h> -#include <stdbool.h> -#include <poll.h> - -#ifndef CONFIG_DEV_PIPE_SIZE -# define CONFIG_DEV_PIPE_SIZE 1024 -#endif - -#if CONFIG_DEV_PIPE_SIZE > 0 - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Maximum number of threads than can be waiting for POLL events */ - -#ifndef CONFIG_DEV_PIPE_NPOLLWAITERS -# define CONFIG_DEV_PIPE_NPOLLWAITERS 2 -#endif - -/* Maximum number of open's supported on pipe */ - -#define CONFIG_DEV_PIPE_MAXUSER 255 - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* Make the buffer index as small as possible for the configured pipe size */ - -#if CONFIG_DEV_PIPE_SIZE > 65535 -typedef uint32_t pipe_ndx_t; /* 32-bit index */ -#elif CONFIG_DEV_PIPE_SIZE > 255 -typedef uint16_t pipe_ndx_t; /* 16-bit index */ -#else -typedef uint8_t pipe_ndx_t; /* 8-bit index */ -#endif - -/* This structure represents the state of one pipe. A reference to this - * structure is retained in the i_private field of the inode whenthe pipe/fifo - * device is registered. - */ - -struct pipe_dev_s -{ - sem_t d_bfsem; /* Used to serialize access to d_buffer and indices */ - sem_t d_rdsem; /* Empty buffer - Reader waits for data write */ - sem_t d_wrsem; /* Full buffer - Writer waits for data read */ - pipe_ndx_t d_wrndx; /* Index in d_buffer to save next byte written */ - pipe_ndx_t d_rdndx; /* Index in d_buffer to return the next byte read */ - uint8_t d_refs; /* References counts on pipe (limited to 255) */ - uint8_t d_nwriters; /* Number of reference counts for write access */ - uint8_t d_pipeno; /* Pipe minor number */ - uint8_t *d_buffer; /* Buffer allocated when device opened */ - - /* The following is a list if poll structures of threads waiting for - * driver events. The 'struct pollfd' reference for each open is also - * retained in the f_priv field of the 'struct file'. - */ - -#ifndef CONFIG_DISABLE_POLL - struct pollfd *d_fds[CONFIG_DEV_PIPE_NPOLLWAITERS]; -#endif -}; - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifdef __cplusplus -# define EXTERN extern "C" -extern "C" { -#else -# define EXTERN extern -#endif - -EXTERN FAR struct pipe_dev_s *pipecommon_allocdev(void); -EXTERN void pipecommon_freedev(FAR struct pipe_dev_s *dev); -EXTERN int pipecommon_open(FAR struct file *filep); -EXTERN int pipecommon_close(FAR struct file *filep); -EXTERN ssize_t pipecommon_read(FAR struct file *, FAR char *, size_t); -EXTERN ssize_t pipecommon_write(FAR struct file *, FAR const char *, size_t); -#ifndef CONFIG_DISABLE_POLL -EXTERN int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup); -#endif - -#undef EXTERN -#ifdef __cplusplus -} -#endif - -#endif /* CONFIG_DEV_PIPE_SIZE > 0 */ -#endif /* __DRIVERS_PIPES_PIPE_COMMON_H */ |