summaryrefslogtreecommitdiffstats
path: root/rtemsbsd/sys
diff options
context:
space:
mode:
authorKevin Kirspel <kevin-kirspel@idexx.com>2017-05-12 08:16:27 -0400
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-05-12 14:20:33 +0200
commit817cbf7201ebd2c27d8e1b8e47a9090762bb010e (patch)
treee2d315cfbe7498d2c3f49473cafb02bcd61e6d6e /rtemsbsd/sys
parentUpdating scripts for USB Serial Drivers (diff)
downloadrtems-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.c154
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,