summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--freebsd/sys/fs/devfs/devfs_vnops.c4
-rw-r--r--freebsd/sys/kern/kern_conf.c4
-rw-r--r--freebsd/sys/sys/file.h7
-rw-r--r--rtemsbsd/sys/fs/devfs/devfs_devs.c154
4 files changed, 145 insertions, 24 deletions
diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c
index b585178f..31231fdd 100644
--- a/freebsd/sys/fs/devfs/devfs_vnops.c
+++ b/freebsd/sys/fs/devfs/devfs_vnops.c
@@ -204,7 +204,11 @@ devfs_destroy_cdevpriv(struct cdev_privdata *p)
free(p, M_CDEVPDATA);
}
+#ifndef __rtems__
static void
+#else /* __rtems__ */
+void
+#endif /* __rtems__ */
devfs_fpdrop(struct file *fp)
{
struct cdev_privdata *p;
diff --git a/freebsd/sys/kern/kern_conf.c b/freebsd/sys/kern/kern_conf.c
index 20f2e2c3..f008fc0c 100644
--- a/freebsd/sys/kern/kern_conf.c
+++ b/freebsd/sys/kern/kern_conf.c
@@ -854,9 +854,7 @@ make_dev_sv(struct make_dev_args *args1, struct cdev **dres,
#endif /* __rtems__ */
devfs_create(dev);
-#ifndef __rtems__
clean_unrhdrl(devfs_inos);
-#endif /* __rtems__ */
dev_unlock_and_free();
notify_create(dev, args.mda_flags);
@@ -1020,9 +1018,7 @@ make_dev_alias_v(int flags, struct cdev **cdev, struct cdev *pdev,
dev->si_flags |= SI_NAMED;
devfs_create(dev);
dev_dependsl(pdev, dev);
-#ifndef __rtems__
clean_unrhdrl(devfs_inos);
-#endif /* __rtems__ */
dev_unlock();
notify_create(dev, flags);
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index 8f91f52c..c52dc7a9 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -199,14 +199,11 @@ struct file {
void *f_label; /* Place-holder for MAC label. */
#else /* __rtems__ */
rtems_libio_t f_io;
- union {
- struct cdev_privdata *fvn_cdevpriv;
- /* (d) Private data for the cdev. */
- } f_vnun;
#endif /* __rtems__ */
};
#ifdef __rtems__
#define f_data f_io.pathinfo.node_access_2
+#define f_cdevpriv f_io.data1
static inline struct file *
rtems_bsd_iop_to_fp(rtems_libio_t *iop)
@@ -283,8 +280,10 @@ rtems_bsd_error_to_status_and_errno(int error)
}
#endif /* __rtems__ */
+#ifndef __rtems__
#define f_cdevpriv f_vnun.fvn_cdevpriv
#define f_advice f_vnun.fvn_advice
+#endif /* __rtems__ */
#define FOFFSET_LOCKED 0x1
#define FOFFSET_LOCK_WAITING 0x2
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,