Index: cpukit/libfs/Makefile.am
===================================================================
--- cpukit/libfs/Makefile.am	(revision 699ac7c08f8e0f7f1a37144e9c316c0dd7a16175)
+++ cpukit/libfs/Makefile.am	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -46,4 +46,5 @@
     src/imfs/imfs_eval.c src/imfs/imfs_fchmod.c \
     src/imfs/imfs_fifo.c \
+    src/imfs/imfs_make_generic_node.c \
     src/imfs/imfs_fsunmount.c \
     src/imfs/imfs_handlers_device.c \
Index: cpukit/libfs/src/imfs/imfs.h
===================================================================
--- cpukit/libfs/src/imfs/imfs.h	(revision 699ac7c08f8e0f7f1a37144e9c316c0dd7a16175)
+++ cpukit/libfs/src/imfs/imfs.h	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -56,4 +56,8 @@
   pipe_control_t  *pipe;
 } IMFS_fifo_t;
+
+typedef struct {
+  void *context;
+} IMFS_generic_t;
 
 /*
@@ -134,7 +138,9 @@
   IMFS_LINEAR_FILE,
   IMFS_FIFO,
+  IMFS_GENERIC,
   IMFS_INVALID_NODE
 } IMFS_jnode_types_t;
 
+/* The IMFS_GENERIC does not count */
 #define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
 
@@ -147,4 +153,5 @@
   IMFS_linearfile_t  linearfile;
   IMFS_fifo_t        fifo;
+  IMFS_generic_t     generic;
 } IMFS_types_union;
 
@@ -155,4 +162,9 @@
 
 IMFS_jnode_t *IMFS_node_initialize_default(
+  IMFS_jnode_t *node,
+  const IMFS_types_union *info
+);
+
+IMFS_jnode_t *IMFS_node_initialize_generic(
   IMFS_jnode_t *node,
   const IMFS_types_union *info
@@ -371,4 +383,15 @@
 );
 
+extern bool IMFS_is_imfs_instance(
+  const rtems_filesystem_location_info_t *loc
+);
+
+extern int IMFS_make_generic_node(
+  const char *path,
+  mode_t mode,
+  const IMFS_node_control *node_control,
+  void *context
+);
+
 extern int IMFS_mount(
   rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
@@ -574,4 +597,27 @@
 }
 
+static inline void *IMFS_generic_get_context_by_node(
+  const IMFS_jnode_t *node
+)
+{
+  return node->info.generic.context;
+}
+
+static inline void *IMFS_generic_get_context_by_location(
+  const rtems_filesystem_location_info_t *loc
+)
+{
+  const IMFS_jnode_t *node = (const IMFS_jnode_t *) loc->node_access;
+
+  return IMFS_generic_get_context_by_node( node );
+}
+
+static inline void *IMFS_generic_get_context_by_iop(
+  const rtems_libio_t *iop
+)
+{
+  return IMFS_generic_get_context_by_location( &iop->pathinfo );
+}
+
 #ifdef __cplusplus
 }
Index: cpukit/libfs/src/imfs/imfs_make_generic_node.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_make_generic_node.c	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
+++ cpukit/libfs/src/imfs/imfs_make_generic_node.c	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "imfs.h"
+
+IMFS_jnode_t *IMFS_node_initialize_generic(
+  IMFS_jnode_t *node,
+  const IMFS_types_union *info
+)
+{
+  node->info.generic.context = info->generic.context;
+
+  return node;
+}
+
+bool IMFS_is_imfs_instance(
+  const rtems_filesystem_location_info_t *loc
+)
+{
+  const char *type = loc->mt_entry->type;
+
+  return strcmp(type, RTEMS_FILESYSTEM_TYPE_IMFS) == 0
+    || strcmp(type, RTEMS_FILESYSTEM_TYPE_MINIIMFS) == 0;
+}
+
+int IMFS_make_generic_node(
+  const char *path,
+  mode_t mode,
+  const IMFS_node_control *node_control,
+  void *context
+)
+{
+  int rv = 0;
+
+  mode &= ~rtems_filesystem_umask;
+
+  switch (mode & S_IFMT) {
+    case S_IFBLK:
+    case S_IFCHR:
+    case S_IFIFO:
+    case S_IFREG:
+      break;
+    default:
+      errno = EINVAL;
+      rv = -1;
+      break;
+  }
+  
+  if ( rv == 0 ) {
+    if ( node_control->imfs_type == IMFS_GENERIC ) {
+      rtems_filesystem_eval_path_context_t ctx;
+      int eval_flags = RTEMS_FS_FOLLOW_LINK
+        | RTEMS_FS_MAKE
+        | RTEMS_FS_EXCLUSIVE;
+      const rtems_filesystem_location_info_t *currentloc =
+        rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
+
+      if ( IMFS_is_imfs_instance( currentloc ) ) {
+        IMFS_types_union info;
+        IMFS_jnode_t *new_node;
+
+        info.generic.context = context;
+        new_node = IMFS_create_node_with_control(
+          currentloc,
+          node_control,
+          rtems_filesystem_eval_path_get_token( &ctx ),
+          rtems_filesystem_eval_path_get_tokenlen( &ctx ),
+          mode,
+          &info
+        );
+
+        if ( new_node != NULL ) {
+          IMFS_jnode_t *parent = currentloc->node_access;
+
+          IMFS_update_ctime( parent );
+          IMFS_update_mtime( parent );
+        } else {
+          rv = -1;
+        }
+      } else {
+        rtems_filesystem_eval_path_error( &ctx, ENOTSUP );
+        rv = -1;
+      }
+
+      rtems_filesystem_eval_path_cleanup( &ctx );
+    } else {
+      errno = EINVAL;
+      rv = -1;
+    }
+  }
+
+  return rv;
+}
Index: testsuites/fstests/Makefile.am
===================================================================
--- testsuites/fstests/Makefile.am	(revision 699ac7c08f8e0f7f1a37144e9c316c0dd7a16175)
+++ testsuites/fstests/Makefile.am	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -32,4 +32,5 @@
 SUBDIRS += mrfs_fstime
 SUBDIRS += fsnofs01
+SUBDIRS += fsimfsgeneric01
 
 EXTRA_DIST =
Index: testsuites/fstests/configure.ac
===================================================================
--- testsuites/fstests/configure.ac	(revision 699ac7c08f8e0f7f1a37144e9c316c0dd7a16175)
+++ testsuites/fstests/configure.ac	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -106,4 +106,5 @@
 mrfs_fstime/Makefile
 fsnofs01/Makefile
+fsimfsgeneric01/Makefile
 
 ])
Index: testsuites/fstests/fsimfsgeneric01/Makefile.am
===================================================================
--- testsuites/fstests/fsimfsgeneric01/Makefile.am	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
+++ testsuites/fstests/fsimfsgeneric01/Makefile.am	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -0,0 +1,20 @@
+rtems_tests_PROGRAMS = fsimfsgeneric01
+fsimfsgeneric01_SOURCES = init.c
+
+dist_rtems_tests_DATA = fsimfsgeneric01.scn fsimfsgeneric01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(fsimfsgeneric01_OBJECTS)
+LINK_LIBS = $(fsimfsgeneric01_LDLIBS)
+
+fsimfsgeneric01$(EXEEXT): $(fsimfsgeneric01_OBJECTS) $(fsimfsgeneric01_DEPENDENCIES)
+	@rm -f fsimfsgeneric01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
Index: testsuites/fstests/fsimfsgeneric01/fsimfsgeneric01.scn
===================================================================
--- testsuites/fstests/fsimfsgeneric01/fsimfsgeneric01.scn	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
+++ testsuites/fstests/fsimfsgeneric01/fsimfsgeneric01.scn	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -0,0 +1,2 @@
+*** TEST FSIMFSGENERIC 1 ***
+*** END OF TEST FSIMFSGENERIC 1 ***
Index: testsuites/fstests/fsimfsgeneric01/init.c
===================================================================
--- testsuites/fstests/fsimfsgeneric01/init.c	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
+++ testsuites/fstests/fsimfsgeneric01/init.c	(revision c5392ef924c0d6f024012f294f39fdb5c6ac2da8)
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "tmacros.h"
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/imfs.h>
+#include <rtems/malloc.h>
+
+typedef enum {
+  TEST_NEW,
+  TEST_INITIALIZED,
+  TEST_FSTAT_OPEN,
+  TEST_OPEN,
+  TEST_READ,
+  TEST_WRITE,
+  TEST_IOCTL,
+  TEST_LSEEK,
+  TEST_FTRUNCATE,
+  TEST_FSYNC,
+  TEST_FDATASYNC,
+  TEST_FCNTL,
+  TEST_CLOSED,
+  TEST_FSTAT_UNLINK,
+  TEST_REMOVED,
+  TEST_DESTROYED
+} test_state;
+
+static test_state global_state = TEST_NEW;
+
+static int handler_open(
+  rtems_libio_t *iop,
+  const char *path,
+  int oflag,
+  mode_t mode
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_FSTAT_OPEN);
+  *state = TEST_OPEN;
+
+  return 0;
+}
+
+static int handler_close(
+  rtems_libio_t *iop
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_FCNTL);
+  *state = TEST_CLOSED;
+
+  return 0;
+}
+
+static ssize_t handler_read(
+  rtems_libio_t *iop,
+  void *buffer,
+  size_t count
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_OPEN);
+  *state = TEST_READ;
+
+  return 0;
+}
+
+static ssize_t handler_write(
+  rtems_libio_t *iop,
+  const void *buffer,
+  size_t count
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_READ);
+  *state = TEST_WRITE;
+
+  return 0;
+}
+
+static int handler_ioctl(
+  rtems_libio_t *iop,
+  uint32_t request,
+  void *buffer
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_WRITE);
+  *state = TEST_IOCTL;
+
+  return 0;
+}
+
+static off_t handler_lseek(
+  rtems_libio_t *iop,
+  off_t length,
+  int whence
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_IOCTL);
+  *state = TEST_LSEEK;
+
+  return 0;
+}
+
+static int handler_fstat(
+  const rtems_filesystem_location_info_t *loc,
+  struct stat *buf
+)
+{
+  test_state *state = IMFS_generic_get_context_by_location(loc);
+
+  switch (*state) {
+    case TEST_INITIALIZED:
+      *state = TEST_FSTAT_OPEN;
+      break;
+    case TEST_CLOSED:
+      *state = TEST_FSTAT_UNLINK;
+      break;
+    default:
+      rtems_test_assert(0);
+      break;
+  }
+
+  return rtems_filesystem_default_fstat(loc, buf);
+}
+
+static int handler_ftruncate(
+  rtems_libio_t *iop,
+  off_t length
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_LSEEK);
+  *state = TEST_FTRUNCATE;
+
+  return 0;
+}
+
+static int handler_fsync(
+  rtems_libio_t *iop
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_FTRUNCATE);
+  *state = TEST_FSYNC;
+
+  return 0;
+}
+
+static int handler_fdatasync(
+  rtems_libio_t *iop
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_FSYNC);
+  *state = TEST_FDATASYNC;
+
+  return 0;
+}
+
+static int handler_fcntl(
+  rtems_libio_t *iop,
+  int cmd
+)
+{
+  test_state *state = IMFS_generic_get_context_by_iop(iop);
+
+  rtems_test_assert(*state == TEST_FDATASYNC);
+  *state = TEST_FCNTL;
+
+  return 0;
+}
+
+static const rtems_filesystem_file_handlers_r node_handlers = {
+  .open_h = handler_open,
+  .close_h = handler_close,
+  .read_h = handler_read,
+  .write_h = handler_write,
+  .ioctl_h = handler_ioctl,
+  .lseek_h = handler_lseek,
+  .fstat_h = handler_fstat,
+  .ftruncate_h = handler_ftruncate,
+  .fsync_h = handler_fsync,
+  .fdatasync_h = handler_fdatasync,
+  .fcntl_h = handler_fcntl
+};
+
+static IMFS_jnode_t *node_initialize(
+  IMFS_jnode_t *node,
+  const IMFS_types_union *info
+)
+{
+  test_state *state = NULL;
+
+  node = IMFS_node_initialize_generic(node, info);
+  state = IMFS_generic_get_context_by_node(node);
+
+  rtems_test_assert(*state == TEST_NEW);
+  *state = TEST_INITIALIZED;
+
+  return node;
+}
+
+static IMFS_jnode_t *node_remove(
+  IMFS_jnode_t *node,
+  const IMFS_jnode_t *root_node
+)
+{
+  test_state *state = IMFS_generic_get_context_by_node(node);
+
+  rtems_test_assert(*state == TEST_FSTAT_UNLINK);
+  *state = TEST_REMOVED;
+
+  return node;
+}
+
+static IMFS_jnode_t *node_destroy(IMFS_jnode_t *node)
+{
+  test_state *state = IMFS_generic_get_context_by_node(node);
+
+  rtems_test_assert(*state == TEST_REMOVED);
+  *state = TEST_DESTROYED;
+
+  return node;
+}
+
+static const IMFS_node_control node_control = {
+  .imfs_type = IMFS_GENERIC,
+  .handlers = &node_handlers,
+  .node_initialize = node_initialize,
+  .node_remove = node_remove,
+  .node_destroy = node_destroy
+};
+
+static void test_imfs_make_generic_node(void)
+{
+  int rv = 0;
+  int fd = 0;
+  const char *path = "generic";
+  char buf [1];
+  ssize_t n = 0;
+  off_t off = 0;
+
+  rv = IMFS_make_generic_node(
+    path,
+    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &node_control,
+    &global_state
+  );
+  rtems_test_assert(rv == 0);
+
+  fd = open(path, O_RDWR);
+  rtems_test_assert(fd >= 0);
+
+  n = read(fd, buf, sizeof(buf));
+  rtems_test_assert(n == 0);
+
+  n = write(fd, buf, sizeof(buf));
+  rtems_test_assert(n == 0);
+
+  rv = ioctl(fd, 0);
+  rtems_test_assert(rv == 0);
+
+  off = lseek(fd, off, SEEK_SET);
+  rtems_test_assert(off == 0);
+
+  rv = ftruncate(fd, 0);
+  rtems_test_assert(rv == 0);
+
+  rv = fsync(fd);
+  rtems_test_assert(rv == 0);
+
+  rv = fdatasync(fd);
+  rtems_test_assert(rv == 0);
+
+  rv = fcntl(fd, F_GETFD);
+  rtems_test_assert(rv >= 0);
+
+  rv = close(fd);
+  rtems_test_assert(rv == 0);
+
+  rv = unlink(path);
+  rtems_test_assert(rv == 0);
+
+  rtems_test_assert(global_state == TEST_DESTROYED);
+}
+
+static const IMFS_node_control node_invalid_control = {
+  .imfs_type = IMFS_DIRECTORY,
+  .handlers = &node_handlers,
+  .node_initialize = node_initialize,
+  .node_remove = node_remove,
+  .node_destroy = node_destroy
+};
+
+static void test_imfs_make_generic_node_errors(void)
+{
+  int rv = 0;
+  const char *path = "generic";
+  rtems_chain_control *chain = &rtems_filesystem_mount_table;
+  rtems_filesystem_mount_table_entry_t *mt_entry =
+    (rtems_filesystem_mount_table_entry_t *) rtems_chain_first(chain);
+  const char *type = mt_entry->type;
+  void *opaque = NULL;
+
+  errno = 0;
+  rv = IMFS_make_generic_node(
+    path,
+    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &node_invalid_control,
+    NULL
+  );
+  rtems_test_assert(rv == -1);
+  rtems_test_assert(errno == EINVAL);
+
+  errno = 0;
+  rv = IMFS_make_generic_node(
+    path,
+    S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &node_control,
+    NULL
+  );
+  rtems_test_assert(rv == -1);
+  rtems_test_assert(errno == EINVAL);
+
+  mt_entry->type = "XXX";
+  errno = 0;
+  rv = IMFS_make_generic_node(
+    path,
+    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &node_control,
+    NULL
+  );
+  rtems_test_assert(rv == -1);
+  rtems_test_assert(errno == ENOTSUP);
+  mt_entry->type = type;
+
+  opaque = rtems_heap_greedy_allocate(0);
+  errno = 0;
+  rv = IMFS_make_generic_node(
+    path,
+    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &node_control,
+    NULL
+  );
+  rtems_test_assert(rv == -1);
+  rtems_test_assert(errno == ENOMEM);
+  rtems_heap_greedy_free(opaque);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  printf("\n\n*** TEST FSIMFSGENERIC 1 ***\n");
+
+  test_imfs_make_generic_node();
+  test_imfs_make_generic_node_errors();
+
+  printf("*** END OF TEST FSIMFSGENERIC 1 ***\n");
+
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
