From 880a17cb0b8a3a47390c9a1904ee82335cc8eabb Mon Sep 17 00:00:00 2001 From: Kevin Kirspel Date: Thu, 4 May 2017 08:27:59 -0400 Subject: Adding RTEMS support for FREEBSD TTY --- rtemsbsd/include/machine/rtems-bsd-commands.h | 2 + rtemsbsd/include/machine/rtems-bsd-kernel-space.h | 1 + rtemsbsd/include/rtems/bsd/local/opt_gdb.h | 1 + rtemsbsd/include/rtems/netcmds-config.h | 2 + rtemsbsd/rtems/rtems-bsd-shell-stty.c | 40 +++++++++++ rtemsbsd/sys/fs/devfs/devfs_devs.c | 86 +++++++++++++++++++++-- 6 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 rtemsbsd/include/rtems/bsd/local/opt_gdb.h create mode 100644 rtemsbsd/rtems/rtems-bsd-shell-stty.c mode change 100755 => 100644 rtemsbsd/sys/fs/devfs/devfs_devs.c diff --git a/rtemsbsd/include/machine/rtems-bsd-commands.h b/rtemsbsd/include/machine/rtems-bsd-commands.h index c0524c8a..9e9ed1c5 100644 --- a/rtemsbsd/include/machine/rtems-bsd-commands.h +++ b/rtemsbsd/include/machine/rtems-bsd-commands.h @@ -70,6 +70,8 @@ int rtems_bsd_command_vmstat(int argc, char **argv); int rtems_bsd_command_wlanstats(int argc, char **argv); +int rtems_bsd_command_stty(int argc, char **argv); + __END_DECLS #endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_COMMANDS_H_ */ diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h index 10ce9d2d..9d0484a4 100644 --- a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h +++ b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h @@ -48,6 +48,7 @@ #define __GLOBL(sym) __GLOBL1(sym) #define O_CLOEXEC 0 +#define IO_NDELAY O_NONBLOCK #define __FreeBSD__ 1 diff --git a/rtemsbsd/include/rtems/bsd/local/opt_gdb.h b/rtemsbsd/include/rtems/bsd/local/opt_gdb.h new file mode 100644 index 00000000..936ffd88 --- /dev/null +++ b/rtemsbsd/include/rtems/bsd/local/opt_gdb.h @@ -0,0 +1 @@ +/* EMPTY */ diff --git a/rtemsbsd/include/rtems/netcmds-config.h b/rtemsbsd/include/rtems/netcmds-config.h index b3bc66f2..515b265e 100644 --- a/rtemsbsd/include/rtems/netcmds-config.h +++ b/rtemsbsd/include/rtems/netcmds-config.h @@ -45,6 +45,8 @@ extern rtems_shell_cmd_t rtems_shell_VMSTAT_Command; extern rtems_shell_cmd_t rtems_shell_WLANSTATS_Command; +extern rtems_shell_cmd_t rtems_shell_STTY_Command; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/rtemsbsd/rtems/rtems-bsd-shell-stty.c b/rtemsbsd/rtems/rtems-bsd-shell-stty.c new file mode 100644 index 00000000..530b442c --- /dev/null +++ b/rtemsbsd/rtems/rtems-bsd-shell-stty.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +#include + +rtems_shell_cmd_t rtems_shell_STTY_Command = { + .name = "stty", + .usage = "stty [args]", + .topic = "serial", + .command = rtems_bsd_command_stty +}; diff --git a/rtemsbsd/sys/fs/devfs/devfs_devs.c b/rtemsbsd/sys/fs/devfs/devfs_devs.c old mode 100755 new mode 100644 index 0ee71ffc..a91a02e7 --- a/rtemsbsd/sys/fs/devfs/devfs_devs.c +++ b/rtemsbsd/sys/fs/devfs/devfs_devs.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -50,8 +51,16 @@ const char rtems_cdev_directory[] = RTEMS_CDEV_DIRECTORY; +/* + * The one true (but secret) list of active devices in the system. + * Locked by dev_lock()/devmtx + */ +struct cdev_priv_list cdevp_list = TAILQ_HEAD_INITIALIZER(cdevp_list); + struct unrhdr *devfs_inos; +static MALLOC_DEFINE(M_CDEVP, "DEVFS1", "DEVFS cdev_priv storage"); + static struct cdev * devfs_imfs_get_context_by_iop(rtems_libio_t *iop) { @@ -62,11 +71,19 @@ static int devfs_imfs_open(rtems_libio_t *iop, const char *path, int oflag, mode_t mode) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); + struct file *fpop; int error; if (td != NULL) { + fpop = td->td_fpop; + curthread->td_fpop = fp; error = cdev->si_devsw->d_open(cdev, oflag, 0, td); + /* Clean up any cdevpriv upon error. */ + if (error != 0) + devfs_clear_cdevpriv(); + curthread->td_fpop = fpop; } else { error = ENOMEM; } @@ -78,12 +95,17 @@ static int devfs_imfs_close(rtems_libio_t *iop) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); int flags = rtems_libio_to_fcntl_flags(iop->flags); + struct file *fpop; int error; if (td != NULL) { + fpop = td->td_fpop; + curthread->td_fpop = fp; error = cdev->si_devsw->d_close(cdev, flags, 0, td); + curthread->td_fpop = fpop; } else { error = ENOMEM; } @@ -96,6 +118,7 @@ devfs_imfs_readv(rtems_libio_t *iop, const struct iovec *iov, int iovcnt, ssize_t total) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); struct uio uio = { .uio_iov = __DECONST(struct iovec *, iov), @@ -106,11 +129,15 @@ devfs_imfs_readv(rtems_libio_t *iop, const struct iovec *iov, int iovcnt, .uio_rw = UIO_READ, .uio_td = td }; + struct file *fpop; int error; if (td != NULL) { + fpop = td->td_fpop; + curthread->td_fpop = fp; error = cdev->si_devsw->d_read(cdev, &uio, rtems_libio_to_fcntl_flags(iop->flags)); + td->td_fpop = fpop; } else { error = ENOMEM; } @@ -138,6 +165,7 @@ devfs_imfs_writev(rtems_libio_t *iop, const struct iovec *iov, int iovcnt, ssize_t total) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); struct uio uio = { .uio_iov = __DECONST(struct iovec *, iov), @@ -148,11 +176,15 @@ devfs_imfs_writev(rtems_libio_t *iop, const struct iovec *iov, int iovcnt, .uio_rw = UIO_WRITE, .uio_td = td }; + struct file *fpop; int error; if (td != NULL) { + fpop = td->td_fpop; + curthread->td_fpop = fp; error = cdev->si_devsw->d_write(cdev, &uio, rtems_libio_to_fcntl_flags(iop->flags)); + td->td_fpop = fpop; } else { error = ENOMEM; } @@ -179,13 +211,18 @@ static int devfs_imfs_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); struct thread *td = rtems_bsd_get_curthread_or_null(); + struct file *fpop; int error; int flags = rtems_libio_to_fcntl_flags(iop->flags); if (td != 0) { + fpop = td->td_fpop; + curthread->td_fpop = fp; error = cdev->si_devsw->d_ioctl(cdev, request, buffer, flags, td); + td->td_fpop = fpop; } else { error = ENOMEM; } @@ -197,17 +234,34 @@ static int devfs_imfs_poll(rtems_libio_t *iop, int events) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); + struct thread *td = rtems_bsd_get_curthread_or_wait_forever(); + struct file *fpop; + int error; + + fpop = td->td_fpop; + curthread->td_fpop = fp; + error = cdev->si_devsw->d_poll(cdev, events, td); + td->td_fpop = fpop; - return (cdev->si_devsw->d_poll(cdev, events, - rtems_bsd_get_curthread_or_wait_forever())); + return error; } static int devfs_imfs_kqfilter(rtems_libio_t *iop, struct knote *kn) { struct cdev *cdev = devfs_imfs_get_context_by_iop(iop); + struct file *fp = rtems_bsd_iop_to_fp(iop); + struct thread *td = rtems_bsd_get_curthread_or_wait_forever(); + struct file *fpop; + int error; + + fpop = td->td_fpop; + curthread->td_fpop = fp; + error = cdev->si_devsw->d_kqfilter(cdev, kn); + td->td_fpop = fpop; - return (cdev->si_devsw->d_kqfilter(cdev, kn)); + return error; } static const rtems_filesystem_file_handlers_r devfs_imfs_handlers = { @@ -235,12 +289,17 @@ static const IMFS_node_control devfs_imfs_control = IMFS_GENERIC_INITIALIZER( struct cdev * devfs_alloc(int flags) { + struct cdev_priv *cdp; struct cdev *cdev; - cdev = malloc(sizeof *cdev, M_TEMP, M_ZERO); - if (cdev == NULL) + cdp = malloc(sizeof *cdp, M_CDEVP, M_ZERO | + ((flags & MAKEDEV_NOWAIT) ? M_NOWAIT : M_WAITOK)); + if (cdp == NULL) return (NULL); + cdev = &cdp->cdp_c; + LIST_INIT(&cdev->si_children); + memcpy(cdev->si_path, rtems_cdev_directory, sizeof(cdev->si_path)); return (cdev); } @@ -248,7 +307,11 @@ devfs_alloc(int flags) void devfs_free(struct cdev *cdev) { - free(cdev, M_TEMP); + struct cdev_priv *cdp; + + cdp = cdev2priv(cdev); + devfs_free_cdp_inode(cdp->cdp_inode); + free(cdp, M_CDEVP); } /* @@ -286,6 +349,7 @@ devfs_create_directory(const char *devname) void devfs_create(struct cdev *dev) { + struct cdev_priv *cdp; int rv; mode_t mode = S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO; @@ -294,13 +358,23 @@ devfs_create(struct cdev *dev) rv = IMFS_make_generic_node(dev->si_path, mode, &devfs_imfs_control, dev); BSD_ASSERT(rv == 0); + + cdp = cdev2priv(dev); + cdp->cdp_flags |= CDP_ACTIVE; + cdp->cdp_inode = alloc_unrl(devfs_inos); + dev_refl(dev); + TAILQ_INSERT_TAIL(&cdevp_list, cdp, cdp_list); } void devfs_destroy(struct cdev *dev) { + struct cdev_priv *cdp; int rv; + cdp = cdev2priv(dev); + cdp->cdp_flags &= ~CDP_ACTIVE; + rv = unlink(dev->si_path); BSD_ASSERT(rv == 0); -- cgit v1.2.3