summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/devfs
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/devfs')
-rw-r--r--cpukit/libfs/src/devfs/devclose.c41
-rw-r--r--cpukit/libfs/src/devfs/devfs.h280
-rw-r--r--cpukit/libfs/src/devfs/devfs_eval.c85
-rw-r--r--cpukit/libfs/src/devfs/devfs_init.c92
-rw-r--r--cpukit/libfs/src/devfs/devfs_mknod.c81
-rw-r--r--cpukit/libfs/src/devfs/devfs_node_type.c26
-rw-r--r--cpukit/libfs/src/devfs/devfs_show.c36
-rw-r--r--cpukit/libfs/src/devfs/devioctl.c45
-rw-r--r--cpukit/libfs/src/devfs/devopen.c42
-rw-r--r--cpukit/libfs/src/devfs/devread.c48
-rw-r--r--cpukit/libfs/src/devfs/devstat.c46
-rw-r--r--cpukit/libfs/src/devfs/devwrite.c48
12 files changed, 870 insertions, 0 deletions
diff --git a/cpukit/libfs/src/devfs/devclose.c b/cpukit/libfs/src/devfs/devclose.c
new file mode 100644
index 0000000000..773cade5c6
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devclose.c
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/io.h>
+
+#include "devfs.h"
+
+int devFS_close(
+ rtems_libio_t *iop
+)
+{
+ rtems_libio_open_close_args_t args;
+ rtems_status_code status;
+ rtems_device_name_t *np;
+
+ np = (rtems_device_name_t *)iop->pathinfo.node_access;
+
+ args.iop = iop;
+ args.flags = 0;
+ args.mode = 0;
+
+ status = rtems_io_close(
+ np->major,
+ np->minor,
+ (void *) &args
+ );
+
+ return rtems_deviceio_errno(status);
+}
+
+
diff --git a/cpukit/libfs/src/devfs/devfs.h b/cpukit/libfs/src/devfs/devfs.h
new file mode 100644
index 0000000000..eafa069cb8
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devfs.h
@@ -0,0 +1,280 @@
+/**
+* @file libfs/devfs/devfs.h
+*
+* This include file contains all constants and structures associated
+* with the 'device-only' filesystem.
+*/
+
+#ifndef _RTEMS_DEVFS_H
+#define _RTEMS_DEVFS_H
+
+#include <rtems/libio_.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This structure define the type of device table
+ */
+
+typedef struct
+{
+ /** This member points to device name which is a null-terminated string */
+ char *device_name;
+ /** This member is the name length of a device */
+ uint32_t device_name_length;
+ /** major number of a device */
+ rtems_device_major_number major;
+ /** minor number of a device */
+ rtems_device_minor_number minor;
+ /** device creation mode, only device file can be created */
+ mode_t mode;
+
+} rtems_device_name_t;
+
+
+
+/**
+ * This routine associates RTEMS status code with errno
+ */
+
+extern int rtems_deviceio_errno(rtems_status_code code);
+
+
+/**
+ * The following defines the device table size. This values
+ * is configured during application configuration time by
+ * the user. The default value is set to 4.
+ */
+
+extern uint32_t rtems_device_table_size;
+
+/**
+ * This handler maps open operation to rtems_io_open.
+ * @param iop This is the RTEMS's internal representation of file.
+ * @param pathname a null-terminated string that starts with /dev.
+ * @param flag access flags
+ * @param mode access mode
+ * @retval the same as open
+ */
+
+extern int devFS_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+);
+
+
+/**
+ * This handler maps close operation to rtems_io_close.
+ * @param iop This is the RTEMS's internal representation of file
+ * @retval the same as close
+ */
+
+
+extern int devFS_close(
+ rtems_libio_t *iop
+);
+
+
+/**
+ * This handler maps read operation to rtems_io_read.
+ * @param iop This is the RTEMS's internal representation of file
+ * @param buffer memory location to store read data
+ * @param count how many bytes to read
+ * @retval On successful, this routine returns total bytes read. On error
+ * it returns -1 and errno is set to proper value.
+ */
+
+extern ssize_t devFS_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+);
+
+
+/**
+ * This handler maps write operation to rtems_io_write.
+ * @param iop This is the RTEMS's internal representation of file
+ * @param buffer data to be written
+ * @param count how many bytes to write
+ * @retval On successful, this routine returns total bytes written. On error
+ * it returns -1 and errno is set to proper value.
+ */
+
+extern ssize_t devFS_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ size_t count
+);
+
+
+/**
+ * This handler maps ioctl operation to rtems_io_ioctl.
+ * @param iop This is the RTEMS's internal representation of file
+ * @param command io control command
+ * @param buffer io control parameters
+ * @retval On successful, this routine returns total bytes written. On error
+ * it returns -1 and errno is set to proper value.
+ */
+
+extern int devFS_ioctl(
+ rtems_libio_t *iop,
+ uint32_t command,
+ void *buffer
+);
+
+
+
+
+/**
+ * This handler gets the device file information. This routine only set the following member of struct stat:
+ * st_dev : device number
+ * st_mode: device file creation mode, only two mode are accepted:
+ * S_IFCHR: character device file
+ * S_IFBLK: block device file
+ * @param loc contains filesystem access information
+ * @param buf buffer to hold the device file's information
+ * @retval On successful, this routine returns 0. On error
+ * it returns -1 and errno is set to proper value.
+ */
+
+extern int devFS_stat(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+
+
+/**
+ * This routine is invoked upon determination of a node type.
+ * Since this is a device-only filesystem, so there is only
+ * one node type in the system.
+ *
+ * @param pathloc contains filesytem access information, this
+ * parameter is ignored
+ * @retval always returns RTEMS_FILESYSTEM_DEVICE
+ */
+
+extern rtems_filesystem_node_types_t devFS_node_type(
+ rtems_filesystem_location_info_t *pathloc
+);
+
+
+
+/**
+ * This routine is invoked to determine if 'pathname' exists.
+ * This routine first check access flags, then it searches
+ * the device table to get the information.
+ *
+ * @param pathname device name to be searched
+ * @param flags access flags
+ * @param pathloc contains filesystem access information
+ * @retval upon success(pathname exists), this routines
+ * returns 0; if 'flag' is invalid, it returns -1 and errno
+ * is set to EIO; otherwise, it returns -1 and errno is set to ENOENT
+ */
+
+extern int devFS_evaluate_path(
+ const char *pathname,
+ size_t pathnamelen,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc
+);
+
+
+/**
+ * This routine is given a path to evaluate and a valid start
+ * location. It is responsible for finding the parent node for
+ * a requested make command, setting pathloc information to
+ * identify the parent node, and setting the name pointer to
+ * the first character of the name of the new node. In device
+ * only filesystem, devices do not has a tree hierarchy, there
+ * are no parent-child relationship. So this routine is rather
+ * simple, it just set *name to path and returns
+ *
+ * @param path device path to be evaluated
+ * @param pathloc contains filesystem access information, this
+ * parameter is ignored
+ * @param name
+ * @retval always returns 0
+ */
+
+extern int devFS_evaluate_for_make(
+ const char *path,
+ rtems_filesystem_location_info_t *pathloc,
+ const char **name
+);
+
+
+
+/**
+ * This routine is invoked upon registration of a new device
+ * file. It is responsible for creating a item in the main
+ * device table. This routine searches the device table in
+ * sequential order, when found a empty slot, it fills the slot
+ * with proper values.
+ *
+ * @param path the device file name to be registered
+ * @param mode file mode, this parameter is ignored
+ * @param dev device major and minor number
+ * @param pathloc contains filesystem access information
+ * @retval upon success, this routine returns 0; if 'path'
+ * already exist, it returns -1 and errno is set to EEXIST;
+ * if device table is full, it returns -1 and errno is set
+ * to ENOMEM
+ */
+
+extern int devFS_mknod(
+ const char *path,
+ mode_t mode,
+ dev_t dev,
+ rtems_filesystem_location_info_t *pathloc
+);
+
+
+/**
+ * This routine is invoked upon rtems filesystem initialization.
+ * It is responsible for creating the main device table,
+ * initializing it to a known state, and set device file operation
+ * handlers. After this, the device-only filesytem is ready for use
+ *
+ * @param mt_entry The filesystem mount table entry.
+ * @param data Filesystem specific data.
+ * @retval upon success, this routine returns 0; otherwise it returns
+ * -1 and errno is set to proper value. The only error is when malloc
+ * failed, and errno is set to NOMEM.
+ */
+
+extern int devFS_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+
+/**
+ * This routine retrieves all the device registered in system, and
+ * prints out their detail information. For example, on one system,
+ * devFS_show will print out following message:
+ *
+ * /dev/console 0 0
+ * /dev/clock 1 0
+ * /dev/tty0 0 0
+ * /flash 2 0
+ *
+ * This routine is intended for debugging, and can be used by shell
+ * program to provide user with the system information.
+ *
+ * @retval 0
+ */
+
+extern int devFS_Show(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/cpukit/libfs/src/devfs/devfs_eval.c b/cpukit/libfs/src/devfs/devfs_eval.c
new file mode 100644
index 0000000000..a3169fb3fa
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devfs_eval.c
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/seterr.h>
+#include <fcntl.h>
+#include <assert.h>
+#include "devfs.h"
+
+/**
+ * The following defines the device-only filesystem operating
+ * handlers.
+ */
+
+extern rtems_filesystem_operations_table devFS_ops;
+
+/**
+ * The following defines the device-only filesystem operating
+ * handlers.
+ */
+
+extern rtems_filesystem_file_handlers_r devFS_file_handlers;
+
+int devFS_evaluate_path(
+ const char *pathname,
+ size_t pathnamelen,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc
+)
+{
+ int i;
+ rtems_device_name_t *device_name_table;
+
+ /* see if 'flags' is valid */
+ if ( !rtems_libio_is_valid_perms( flags ) )
+ rtems_set_errno_and_return_minus_one( EPERM );
+
+ /* get the device name table */
+ device_name_table = (rtems_device_name_t *)pathloc->node_access;
+ if (!device_name_table)
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ for (i = 0; i < rtems_device_table_size; i++) {
+ if (!device_name_table[i].device_name)
+ continue;
+
+ if (strncmp(pathname, device_name_table[i].device_name, pathnamelen) != 0)
+ continue;
+
+ if (device_name_table[i].device_name[pathnamelen] != '\0')
+ continue;
+
+ /* find the device, set proper values */
+ pathloc->node_access = (void *)&device_name_table[i];
+ pathloc->handlers = &devFS_file_handlers;
+ pathloc->ops = &devFS_ops;
+ pathloc->mt_entry = rtems_filesystem_root.mt_entry;
+ return 0;
+ }
+
+ /* no such file or directory */
+ rtems_set_errno_and_return_minus_one( ENOENT );
+}
+
+
+
+int devFS_evaluate_for_make(
+ const char *path,
+ rtems_filesystem_location_info_t *pathloc,
+ const char **name
+)
+{
+ /* we do nothing, just set name to path */
+ *name = path;
+ return 0;
+}
+
diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c
new file mode 100644
index 0000000000..5f6521a045
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devfs_init.c
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <rtems.h>
+#include <rtems/seterr.h>
+#include <rtems/score/wkspace.h>
+#include "devfs.h"
+
+rtems_filesystem_operations_table devFS_ops =
+{
+ devFS_evaluate_path,
+ devFS_evaluate_for_make,
+ rtems_filesystem_default_link,
+ rtems_filesystem_default_unlink,
+ devFS_node_type,
+ devFS_mknod,
+ rtems_filesystem_default_chown,
+ rtems_filesystem_default_freenode,
+ rtems_filesystem_default_mount,
+ devFS_initialize,
+ rtems_filesystem_default_unmount,
+ rtems_filesystem_default_fsunmount,
+ rtems_filesystem_default_utime,
+ rtems_filesystem_default_evaluate_link,
+ rtems_filesystem_default_symlink,
+ rtems_filesystem_default_readlink,
+ rtems_filesystem_default_rename,
+ rtems_filesystem_default_statvfs
+};
+
+
+rtems_filesystem_file_handlers_r devFS_file_handlers =
+{
+ devFS_open,
+ devFS_close,
+ devFS_read,
+ devFS_write,
+ devFS_ioctl,
+ rtems_filesystem_default_lseek,
+ devFS_stat,
+ rtems_filesystem_default_fchmod,
+ rtems_filesystem_default_ftruncate,
+ rtems_filesystem_default_fpathconf,
+ rtems_filesystem_default_fsync,
+ rtems_filesystem_default_fdatasync,
+ rtems_filesystem_default_fcntl,
+ rtems_filesystem_default_rmnod
+};
+
+
+
+int devFS_initialize(
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry,
+ const void *data
+)
+{
+ rtems_device_name_t *device_name_table;
+
+ /* allocate device only filesystem name table */
+ device_name_table = (rtems_device_name_t *)_Workspace_Allocate(
+ sizeof( rtems_device_name_t ) * ( rtems_device_table_size )
+ );
+
+ /* no memory for device filesystem */
+ if (!device_name_table)
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+
+ memset(
+ device_name_table, 0,
+ sizeof( rtems_device_name_t ) * ( rtems_device_table_size )
+ );
+
+ /* set file handlers */
+ temp_mt_entry->mt_fs_root.handlers = &devFS_file_handlers;
+ temp_mt_entry->mt_fs_root.ops = &devFS_ops;
+
+ /* Set the node_access to device name table */
+ temp_mt_entry->mt_fs_root.node_access = (void *)device_name_table;
+
+ return 0;
+}
+
diff --git a/cpukit/libfs/src/devfs/devfs_mknod.c b/cpukit/libfs/src/devfs/devfs_mknod.c
new file mode 100644
index 0000000000..d8e5a30d5f
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devfs_mknod.c
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <rtems/seterr.h>
+#include "devfs.h"
+
+int devFS_mknod(
+ const char *path,
+ mode_t mode,
+ dev_t dev,
+ rtems_filesystem_location_info_t *pathloc
+)
+{
+ int i;
+ int slot;
+ rtems_device_name_t *device_name_table;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ ISR_Level level;
+
+ /*
+ * This is a special case. In rtems_filesystem_initialize,
+ * a special device '/dev' will be created. We check this
+ * condition and do not create the '/dev' and the 'path'
+ * actually passed in is 'dev', not '/dev'. Just return 0 to
+ * indicate we are OK.
+ */
+
+ if ((path[0] == 'd') && (path[1] == 'e') &&
+ (path[2] == 'v') && (path[3] == '\0'))
+ return 0;
+
+ /* must be a character device or a block device */
+ if (!S_ISBLK(mode) && !S_ISCHR(mode))
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ else
+ rtems_filesystem_split_dev_t(dev, major, minor);
+
+ /* Find an empty slot in device name table */
+ device_name_table = (rtems_device_name_t *)pathloc->node_access;
+ if (!device_name_table)
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ for (slot = -1, i = 0; i < rtems_device_table_size; i++){
+ if (device_name_table[i].device_name == NULL)
+ slot = i;
+ else
+ if (strcmp(path, device_name_table[i].device_name) == 0)
+ rtems_set_errno_and_return_minus_one( EEXIST );
+ }
+
+ if (slot == -1)
+ rtems_set_errno_and_return_minus_one( ENOMEM );
+
+ _ISR_Disable(level);
+ device_name_table[slot].device_name = (char *)path;
+ device_name_table[slot].device_name_length = strlen(path);
+ device_name_table[slot].major = major;
+ device_name_table[slot].minor = minor;
+ device_name_table[slot].mode = mode;
+ _ISR_Enable(level);
+
+ return 0;
+}
+
diff --git a/cpukit/libfs/src/devfs/devfs_node_type.c b/cpukit/libfs/src/devfs/devfs_node_type.c
new file mode 100644
index 0000000000..0bede52d2d
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devfs_node_type.c
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "devfs.h"
+
+rtems_filesystem_node_types_t devFS_node_type(
+ rtems_filesystem_location_info_t *pathloc
+)
+{
+ /*
+ * There is only one type of node: device
+ */
+
+ return RTEMS_FILESYSTEM_DEVICE;
+}
+
+
diff --git a/cpukit/libfs/src/devfs/devfs_show.c b/cpukit/libfs/src/devfs/devfs_show.c
new file mode 100644
index 0000000000..e449caf49f
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devfs_show.c
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/seterr.h>
+#include "devfs.h"
+
+int devFS_Show(void)
+{
+ int i;
+ rtems_filesystem_location_info_t *temp_loc;
+ rtems_device_name_t *device_name_table;
+
+ temp_loc = &rtems_filesystem_root;
+ device_name_table = (rtems_device_name_t *)temp_loc->node_access;
+ if (!device_name_table)
+ rtems_set_errno_and_return_minus_one( EFAULT );
+
+ for (i = 0; i < rtems_device_table_size; i++){
+ if (device_name_table[i].device_name){
+ printk("/%s %d %d\n", device_name_table[i].device_name,
+ device_name_table[i].major, device_name_table[i].minor);
+ }
+ }
+ return 0;
+}
+
+
diff --git a/cpukit/libfs/src/devfs/devioctl.c b/cpukit/libfs/src/devfs/devioctl.c
new file mode 100644
index 0000000000..15965b8c0e
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devioctl.c
@@ -0,0 +1,45 @@
+#if HAVE_CONFIG_H
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/io.h>
+
+#include "devfs.h"
+
+int devFS_ioctl(
+ rtems_libio_t *iop,
+ uint32_t command,
+ void *buffer
+)
+{
+ rtems_libio_ioctl_args_t args;
+ rtems_status_code status;
+ rtems_device_name_t *np;
+
+ np = (rtems_device_name_t *)iop->pathinfo.node_access;
+
+ args.iop = iop;
+ args.command = command;
+ args.buffer = buffer;
+
+ status = rtems_io_control(
+ np->major,
+ np->minor,
+ (void *) &args
+ );
+
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return args.ioctl_return;
+}
+
diff --git a/cpukit/libfs/src/devfs/devopen.c b/cpukit/libfs/src/devfs/devopen.c
new file mode 100644
index 0000000000..67be3678e1
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devopen.c
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/io.h>
+
+#include "devfs.h"
+
+int devFS_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+)
+{
+ rtems_libio_open_close_args_t args;
+ rtems_status_code status;
+ rtems_device_name_t *np;
+
+ np = (rtems_device_name_t *)iop->pathinfo.node_access;
+
+ args.iop = iop;
+ args.flags = iop->flags;
+ args.mode = mode;
+
+ status = rtems_io_open(
+ np->major,
+ np->minor,
+ (void *) &args
+ );
+
+ return rtems_deviceio_errno(status);
+}
diff --git a/cpukit/libfs/src/devfs/devread.c b/cpukit/libfs/src/devfs/devread.c
new file mode 100644
index 0000000000..10f74e81c9
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devread.c
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/io.h>
+
+#include "devfs.h"
+
+ssize_t devFS_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+)
+{
+ rtems_libio_rw_args_t args;
+ rtems_status_code status;
+ rtems_device_name_t *np;
+
+ np = (rtems_device_name_t *)iop->pathinfo.node_access;
+
+ args.iop = iop;
+ args.offset = iop->offset;
+ args.buffer = buffer;
+ args.count = count;
+ args.flags = iop->flags;
+ args.bytes_moved = 0;
+
+ status = rtems_io_read(
+ np->major,
+ np->minor,
+ (void *) &args
+ );
+
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return (ssize_t) args.bytes_moved;
+}
+
diff --git a/cpukit/libfs/src/devfs/devstat.c b/cpukit/libfs/src/devfs/devstat.c
new file mode 100644
index 0000000000..db17595621
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devstat.c
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/io.h>
+#include <rtems/seterr.h>
+#include <rtems/libio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "devfs.h"
+
+int devFS_stat(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+)
+{
+ rtems_device_name_t *the_dev;
+
+ the_dev = (rtems_device_name_t *)loc->node_access;
+
+ /*
+ * stat() invokes devFS_evaluate_path() which checks that node_access
+ * is not NULL. So this should NEVER be NULL unless someone breaks
+ * other code in this filesystem.
+ */
+ #if defined(RTEMS_DEBUG)
+ if (!the_dev)
+ rtems_set_errno_and_return_minus_one( EFAULT );
+ #endif
+
+ buf->st_rdev = rtems_filesystem_make_dev_t( the_dev->major, the_dev->minor );
+ buf->st_mode = the_dev->mode;
+ return 0;
+}
+
+
diff --git a/cpukit/libfs/src/devfs/devwrite.c b/cpukit/libfs/src/devfs/devwrite.c
new file mode 100644
index 0000000000..5389c69bc5
--- /dev/null
+++ b/cpukit/libfs/src/devfs/devwrite.c
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/io.h>
+
+#include "devfs.h"
+
+ssize_t devFS_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ size_t count
+)
+{
+ rtems_libio_rw_args_t args;
+ rtems_status_code status;
+ rtems_device_name_t *np;
+
+ np = (rtems_device_name_t *)iop->pathinfo.node_access;
+
+ args.iop = iop;
+ args.offset = iop->offset;
+ args.buffer = (void *) buffer;
+ args.count = count;
+ args.flags = iop->flags;
+ args.bytes_moved = 0;
+
+ status = rtems_io_write(
+ np->major,
+ np->minor,
+ (void *) &args
+ );
+
+ if ( status )
+ return rtems_deviceio_errno(status);
+
+ return (ssize_t) args.bytes_moved;
+}
+