Index: rtemsbsd/include/machine/rtems-bsd-commands.h
===================================================================
--- rtemsbsd/include/machine/rtems-bsd-commands.h	(revision 4a8f953f62f38be118a9aa3cdce87743ec898015)
+++ rtemsbsd/include/machine/rtems-bsd-commands.h	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
@@ -71,4 +71,6 @@
 int rtems_bsd_command_wlanstats(int argc, char **argv);
 
+int rtems_bsd_command_stty(int argc, char **argv);
+
 __END_DECLS
 
Index: rtemsbsd/include/machine/rtems-bsd-kernel-space.h
===================================================================
--- rtemsbsd/include/machine/rtems-bsd-kernel-space.h	(revision 4a8f953f62f38be118a9aa3cdce87743ec898015)
+++ rtemsbsd/include/machine/rtems-bsd-kernel-space.h	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
@@ -49,4 +49,5 @@
 
 #define O_CLOEXEC 0
+#define IO_NDELAY O_NONBLOCK
 
 #define __FreeBSD__ 1
Index: rtemsbsd/include/rtems/bsd/local/opt_gdb.h
===================================================================
--- rtemsbsd/include/rtems/bsd/local/opt_gdb.h	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
+++ rtemsbsd/include/rtems/bsd/local/opt_gdb.h	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
@@ -0,0 +1,1 @@
+/* EMPTY */
Index: rtemsbsd/include/rtems/netcmds-config.h
===================================================================
--- rtemsbsd/include/rtems/netcmds-config.h	(revision 4a8f953f62f38be118a9aa3cdce87743ec898015)
+++ rtemsbsd/include/rtems/netcmds-config.h	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
@@ -46,4 +46,6 @@
 extern rtems_shell_cmd_t rtems_shell_WLANSTATS_Command;
 
+extern rtems_shell_cmd_t rtems_shell_STTY_Command;
+
 #ifdef __cplusplus
 }
Index: rtemsbsd/rtems/rtems-bsd-shell-stty.c
===================================================================
--- rtemsbsd/rtems/rtems-bsd-shell-stty.c	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
+++ rtemsbsd/rtems/rtems-bsd-shell-stty.c	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * 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 <rtems/netcmds-config.h>
+#include <machine/rtems-bsd-commands.h>
+
+rtems_shell_cmd_t rtems_shell_STTY_Command = {
+  .name = "stty",
+  .usage = "stty [args]",
+  .topic = "serial",
+  .command = rtems_bsd_command_stty
+};
Index: rtemsbsd/sys/fs/devfs/devfs_devs.c
===================================================================
--- rtemsbsd/sys/fs/devfs/devfs_devs.c	(revision 4a8f953f62f38be118a9aa3cdce87743ec898015)
+++ rtemsbsd/sys/fs/devfs/devfs_devs.c	(revision 880a17cb0b8a3a47390c9a1904ee82335cc8eabb)
@@ -37,4 +37,5 @@
 #include <sys/file.h>
 #include <sys/malloc.h>
+#include <sys/proc.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,5 +52,13 @@
 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 *
@@ -63,9 +72,17 @@
 {
 	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;
@@ -79,10 +96,15 @@
 {
 	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;
@@ -97,4 +119,5 @@
 {
 	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 = {
@@ -107,9 +130,13 @@
 		.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;
@@ -139,4 +166,5 @@
 {
 	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 = {
@@ -149,9 +177,13 @@
 		.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;
@@ -180,11 +212,16 @@
 {
 	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;
@@ -198,7 +235,15 @@
 {
 	struct cdev *cdev = devfs_imfs_get_context_by_iop(iop);
-
-	return (cdev->si_devsw->d_poll(cdev, events,
-	    rtems_bsd_get_curthread_or_wait_forever()));
+	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 error;
 }
 
@@ -207,6 +252,15 @@
 {
 	struct cdev *cdev = devfs_imfs_get_context_by_iop(iop);
-
-	return (cdev->si_devsw->d_kqfilter(cdev, 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;
+
+	fpop = td->td_fpop;
+	curthread->td_fpop = fp;
+	error = cdev->si_devsw->d_kqfilter(cdev, kn);
+	td->td_fpop = fpop;
+
+	return error;
 }
 
@@ -236,9 +290,14 @@
 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));
@@ -249,5 +308,9 @@
 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);
 }
 
@@ -287,4 +350,5 @@
 devfs_create(struct cdev *dev)
 {
+	struct cdev_priv *cdp;
 	int rv;
 	mode_t mode = S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO;
@@ -295,4 +359,10 @@
 	    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);
 }
 
@@ -300,5 +370,9 @@
 devfs_destroy(struct cdev *dev)
 {
+	struct cdev_priv *cdp;
 	int rv;
+
+	cdp = cdev2priv(dev);
+	cdp->cdp_flags &= ~CDP_ACTIVE;
 
 	rv = unlink(dev->si_path);
