diff options
author | Kevin Kirspel <kevin-kirspel@idexx.com> | 2017-05-12 08:16:27 -0400 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-05-12 14:20:33 +0200 |
commit | 817cbf7201ebd2c27d8e1b8e47a9090762bb010e (patch) | |
tree | e2d315cfbe7498d2c3f49473cafb02bcd61e6d6e /rtemsbsd/sys | |
parent | Updating scripts for USB Serial Drivers (diff) | |
download | rtems-libbsd-817cbf7201ebd2c27d8e1b8e47a9090762bb010e.tar.bz2 |
devfs: Fix some issues
Fix issue with cdev private data usage with RTEMS iop structure. Add
support for cdev alias device names. Add support for cdev fstat.
Diffstat (limited to 'rtemsbsd/sys')
-rw-r--r-- | rtemsbsd/sys/fs/devfs/devfs_devs.c | 154 |
1 files changed, 138 insertions, 16 deletions
diff --git a/rtemsbsd/sys/fs/devfs/devfs_devs.c b/rtemsbsd/sys/fs/devfs/devfs_devs.c index a91a02e7..7d89c49e 100644 --- a/rtemsbsd/sys/fs/devfs/devfs_devs.c +++ b/rtemsbsd/sys/fs/devfs/devfs_devs.c @@ -37,6 +37,7 @@ #include <sys/file.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/poll.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -74,20 +75,40 @@ devfs_imfs_open(rtems_libio_t *iop, const char *path, int oflag, mode_t mode) struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; if (td != NULL) { + if (cdev == NULL) { + error = ENXIO; + goto err; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + error = ENXIO; + goto err; + } + if (fp == NULL) { + dev_relthread(cdev, ref); + error = ENXIO; + goto err; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_open(cdev, oflag, 0, td); + error = dsw->d_open(cdev, oflag + 1, 0, td); /* Clean up any cdevpriv upon error. */ if (error != 0) devfs_clear_cdevpriv(); curthread->td_fpop = fpop; + dev_relthread(cdev, ref); } else { error = ENOMEM; } +err: return rtems_bsd_error_to_status_and_errno(error); } @@ -99,17 +120,34 @@ devfs_imfs_close(rtems_libio_t *iop) struct thread *td = rtems_bsd_get_curthread_or_null(); int flags = rtems_libio_to_fcntl_flags(iop->flags); struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; if (td != NULL) { + if (cdev == NULL) { + error = ENXIO; + goto err; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + error = ENXIO; + goto err; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_close(cdev, flags, 0, td); + error = dsw->d_close(cdev, flags, 0, td); curthread->td_fpop = fpop; + dev_relthread(cdev, ref); + if (fp->f_cdevpriv != NULL) + devfs_fpdrop(fp); } else { error = ENOMEM; } +err: return rtems_bsd_error_to_status_and_errno(error); } @@ -130,18 +168,33 @@ devfs_imfs_readv(rtems_libio_t *iop, const struct iovec *iov, int iovcnt, .uio_td = td }; struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; if (td != NULL) { + if (cdev == NULL) { + error = ENXIO; + goto err; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + error = ENXIO; + goto err; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_read(cdev, &uio, + error = dsw->d_read(cdev, &uio, rtems_libio_to_fcntl_flags(iop->flags)); td->td_fpop = fpop; + dev_relthread(cdev, ref); } else { error = ENOMEM; } +err: if (error == 0) { return (total - uio.uio_resid); } else { @@ -177,18 +230,33 @@ devfs_imfs_writev(rtems_libio_t *iop, const struct iovec *iov, int iovcnt, .uio_td = td }; struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; if (td != NULL) { + if (cdev == NULL) { + error = ENXIO; + goto err; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + error = ENXIO; + goto err; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_write(cdev, &uio, + error = dsw->d_write(cdev, &uio, rtems_libio_to_fcntl_flags(iop->flags)); td->td_fpop = fpop; + dev_relthread(cdev, ref); } else { error = ENOMEM; } +err: if (error == 0) { return (total - uio.uio_resid); } else { @@ -214,20 +282,50 @@ devfs_imfs_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer) struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; int flags = rtems_libio_to_fcntl_flags(iop->flags); if (td != 0) { + if (cdev == NULL) { + error = ENXIO; + goto err; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + error = ENXIO; + goto err; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_ioctl(cdev, request, buffer, flags, + error = dsw->d_ioctl(cdev, request, buffer, flags, td); td->td_fpop = fpop; + dev_relthread(cdev, ref); } else { error = ENOMEM; } - return (rtems_bsd_error_to_status_and_errno(error)); +err: + return rtems_bsd_error_to_status_and_errno(error); +} + +static int +devfs_imfs_fstat(const rtems_filesystem_location_info_t *loc, struct stat *buf) +{ + int rv = 0; + const IMFS_jnode_t *the_dev = loc->node_access; + + if (the_dev != NULL) { + buf->st_mode = the_dev->st_mode; + } else { + rv = rtems_filesystem_default_fstat(loc, buf); + } + + return rv; } static int @@ -237,12 +335,24 @@ devfs_imfs_poll(rtems_libio_t *iop, int events) struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_wait_forever(); struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; + if (cdev == NULL) { + return POLLERR; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + return POLLERR; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_poll(cdev, events, td); + error = dsw->d_poll(cdev, events, td); td->td_fpop = fpop; + dev_relthread(cdev, ref); return error; } @@ -254,12 +364,24 @@ devfs_imfs_kqfilter(rtems_libio_t *iop, struct knote *kn) struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_wait_forever(); struct file *fpop; - int error; + struct cdevsw *dsw; + int error, ref; + if (cdev == NULL) { + return EINVAL; + } + if (cdev->si_flags & SI_ALIAS) { + cdev = cdev->si_parent; + } + dsw = dev_refthread(cdev, &ref); + if (dsw == NULL) { + return EINVAL; + } fpop = td->td_fpop; curthread->td_fpop = fp; - error = cdev->si_devsw->d_kqfilter(cdev, kn); + error = dsw->d_kqfilter(cdev, kn); td->td_fpop = fpop; + dev_relthread(cdev, ref); return error; } @@ -271,7 +393,7 @@ static const rtems_filesystem_file_handlers_r devfs_imfs_handlers = { .write_h = devfs_imfs_write, .ioctl_h = devfs_imfs_ioctl, .lseek_h = rtems_filesystem_default_lseek_file, - .fstat_h = rtems_filesystem_default_fstat, + .fstat_h = devfs_imfs_fstat, .ftruncate_h = rtems_filesystem_default_ftruncate, .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, |