diff options
29 files changed, 1082 insertions, 81 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 048bb0be4f..49437b8323 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,26 @@ +2008-09-17 Miao Yan <yanmiaobest@gmail.com> + + * Makefile.am, preinstall.am, libcsupport/Makefile.am, + libcsupport/include/rtems/libcsupport.h, + libcsupport/include/rtems/libio.h, libcsupport/src/base_fs.c, + libcsupport/src/libio_init.c, libcsupport/src/newlibc_exit.c, + libcsupport/src/newlibc_init.c, libcsupport/src/sync.c, + libfs/Makefile.am, libfs/src/imfs/deviceio.c, + sapi/include/confdefs.h: Merge GSOC project code to add simple device + only filesystem (devfs), optionally completely drop out filesystem, + and to clean up disabling newlib reentrancy support. This dropped 17K + from the minimum.exe for sparc/sis and arm/rtl22xx_t now has a 15K + code space. + * libcsupport/src/__usrenv.c, libcsupport/src/newlibc_reent.c, + libfs/src/devfs/devclose.c, libfs/src/devfs/devfs.h, + libfs/src/devfs/devfs_eval.c, libfs/src/devfs/devfs_init.c, + libfs/src/devfs/devfs_mknod.c, libfs/src/devfs/devfs_node_type.c, + libfs/src/devfs/devfs_show.c, libfs/src/devfs/devioctl.c, + libfs/src/devfs/devopen.c, libfs/src/devfs/devread.c, + libfs/src/devfs/devstat.c, libfs/src/devfs/devwrite.c, + libfs/src/imfs/deviceerrno.c: New files. + * libcsupport/src/newlibc.c: Removed. + 2008-09-16 Joel Sherrill <joel.sherrill@OARcorp.com> * sapi/include/confdefs.h: Revert previous patch. Does not apply to diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index 35900e7325..e9d916a0c6 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -79,6 +79,9 @@ include_rtems_HEADERS += include/rtems/irq-extension.h ## libfs include_rtems_HEADERS += libfs/src/imfs/imfs.h +## devfs +include_rtems_HEADERS += libfs/src/devfs/devfs.h + if LIBDOSFS include_rtems_HEADERS += libfs/src/dosfs/dosfs.h endif diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index f5cb6fdae3..12395b1af7 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -47,7 +47,7 @@ ASSOCIATION_C_FILES = src/assoclocalbyname.c \ BASE_FS_C_FILES = src/base_fs.c src/mount.c src/unmount.c src/libio.c \ src/libio_init.c \ src/libio_sockets.c src/eval.c src/fs_null_handlers.c src/privateenv.c \ - src/open_dev_console.c + src/open_dev_console.c src/__usrenv.c TERMIOS_C_FILES = src/cfgetispeed.c src/cfgetospeed.c src/cfsetispeed.c \ src/cfsetospeed.c src/tcgetattr.c src/tcsetattr.c src/tcdrain.c \ @@ -94,7 +94,7 @@ TERMINAL_IDENTIFICATION_C_FILES = src/ctermid.c src/isatty.c src/ttyname.c LIBC_GLUE_C_FILES = src/__getpid.c src/__gettod.c src/__times.c \ src/truncate.c src/access.c src/stat.c src/lstat.c src/pathconf.c \ - src/newlibc.c src/newlibc_init.c src/newlibc_exit.c src/no_posix.c \ + src/newlibc_reent.c src/newlibc_init.c src/newlibc_exit.c src/no_posix.c \ src/no_libc.c src/utsname.c BSD_LIBC_C_FILES = src/strlcpy.c src/strlcat.c diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h index 2c6efd1536..7197df5708 100644 --- a/cpukit/libcsupport/include/rtems/libcsupport.h +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -45,33 +45,33 @@ extern void open_dev_console(void); /* * Prototypes required to install newlib reentrancy user extension */ -bool libc_create_hook( +bool newlib_create_hook( rtems_tcb *current_task, rtems_tcb *creating_task ); #if defined(RTEMS_UNIX) && !defined(hpux) - rtems_extension libc_begin_hook(rtems_tcb *current_task); - #define __RTEMS_NEWLIB_BEGIN libc_begin_hook + rtems_extension newlib_begin_hook(rtems_tcb *current_task); + #define __RTEMS_NEWLIB_BEGIN newlib_begin_hook #else #define __RTEMS_NEWLIB_BEGIN 0 #endif -rtems_extension libc_delete_hook( +rtems_extension newlib_delete_hook( rtems_tcb *current_task, rtems_tcb *deleted_task ); #define RTEMS_NEWLIB_EXTENSION \ { \ - libc_create_hook, /* rtems_task_create */ \ - 0, /* rtems_task_start */ \ - 0, /* rtems_task_restart */ \ - libc_delete_hook, /* rtems_task_delete */ \ - 0, /* task_switch */ \ - __RTEMS_NEWLIB_BEGIN, /* task_begin */ \ - 0, /* task_exitted */ \ - 0 /* fatal */ \ + newlib_create_hook, /* rtems_task_create */ \ + 0, /* rtems_task_start */ \ + 0, /* rtems_task_restart */ \ + newlib_delete_hook, /* rtems_task_delete */ \ + 0, /* task_switch */ \ + __RTEMS_NEWLIB_BEGIN, /* task_begin */ \ + 0, /* task_exitted */ \ + 0 /* fatal */ \ } #ifdef __cplusplus diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h index 1767d1d789..9147218629 100644 --- a/cpukit/libcsupport/include/rtems/libio.h +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -634,6 +634,18 @@ typedef struct { extern const rtems_filesystem_mount_table_t *rtems_filesystem_mount_table; extern const int rtems_filesystem_mount_table_size; + +typedef void (*rtems_libio_init_functions_t)(void); +extern rtems_libio_init_functions_t rtems_libio_init_helper; + +void open_dev_console(void); + +typedef void (*rtems_libio_supp_functions_t)(void); +extern rtems_libio_supp_functions_t rtems_libio_supp_helper; + +typedef void (*rtems_fs_init_functions_t)(void); +extern rtems_fs_init_functions_t rtems_fs_init_helper; + #ifdef __cplusplus } #endif diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c new file mode 100644 index 0000000000..0b3469fa1a --- /dev/null +++ b/cpukit/libcsupport/src/__usrenv.c @@ -0,0 +1,27 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * 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/libio.h> +#include <rtems/libio_.h> + +/* + * Global information for POSIX Process Environment Support + */ + +rtems_user_env_t rtems_global_user_env; +rtems_user_env_t * rtems_current_user_env = &rtems_global_user_env; + + diff --git a/cpukit/libcsupport/src/base_fs.c b/cpukit/libcsupport/src/base_fs.c index 4ce53b0e4b..91466a5b07 100644 --- a/cpukit/libcsupport/src/base_fs.c +++ b/cpukit/libcsupport/src/base_fs.c @@ -1,7 +1,7 @@ /* * Base file system initialization * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -20,13 +20,6 @@ #include <rtems/libio_.h> /* - * Global information for the base file system. - */ - -rtems_user_env_t rtems_global_user_env; -rtems_user_env_t * rtems_current_user_env = &rtems_global_user_env; - -/* * Default mode for created files. */ diff --git a/cpukit/libcsupport/src/libio_init.c b/cpukit/libcsupport/src/libio_init.c index 4968058637..9bb96e40c2 100644 --- a/cpukit/libcsupport/src/libio_init.c +++ b/cpukit/libcsupport/src/libio_init.c @@ -86,5 +86,6 @@ void rtems_libio_init( void ) * Initialize the base file system infrastructure. */ - rtems_filesystem_initialize(); + if (rtems_fs_init_helper) + (* rtems_fs_init_helper)(); } diff --git a/cpukit/libcsupport/src/newlibc_exit.c b/cpukit/libcsupport/src/newlibc_exit.c index 68212b692e..f7f8a6e481 100644 --- a/cpukit/libcsupport/src/newlibc_exit.c +++ b/cpukit/libcsupport/src/newlibc_exit.c @@ -40,7 +40,7 @@ int _fwalk(struct _reent *ptr, int (*function) (FILE *) ); /* do we think we are reentrant? */ extern int libc_reentrant; -extern struct _reent libc_global_reent __ATTRIBUTE_IMPURE_PTR__; +extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; /* * CYGNUS newlib routine that does atexit() processing and flushes @@ -66,15 +66,15 @@ void libc_wrapup(void) _wrapup_reent(0); */ - if (_REENT != &libc_global_reent) { - _wrapup_reent(&libc_global_reent); + if (_REENT != _global_impure_ptr) { + _wrapup_reent(_global_impure_ptr); #if 0 /* Don't reclaim this one, just in case we do printfs * on the way out to ROM. */ _reclaim_reent(&libc_global_reent); #endif - _REENT = &libc_global_reent; + _REENT = _global_impure_ptr; } /* diff --git a/cpukit/libcsupport/src/newlibc_init.c b/cpukit/libcsupport/src/newlibc_init.c index a37ab29663..dbf9544fd5 100644 --- a/cpukit/libcsupport/src/newlibc_init.c +++ b/cpukit/libcsupport/src/newlibc_init.c @@ -17,22 +17,7 @@ #include "config.h" #endif -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ -#include <rtems.h> - #if defined(RTEMS_NEWLIB) -#include <rtems/libcsupport.h> - -/* Since we compile with strict ANSI we need to undef it to get - * prototypes for extensions - */ -#undef __STRICT_ANSI__ - -#include <stdlib.h> /* for free() */ -#include <string.h> /* for memset() */ - -#include <sys/reent.h> /* for extern of _REENT (aka _impure_ptr) */ -#include <errno.h> /* * Init libc for CYGNUS newlib @@ -48,14 +33,9 @@ */ -struct _reent libc_global_reent - __ATTRIBUTE_IMPURE_PTR__ = _REENT_INIT(libc_global_reent); void libc_init(void) { - _REENT = &libc_global_reent; - - _Thread_Set_libc_reent (&_REENT); } #endif diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc_reent.c index 79c1dc7dd4..ba8078a135 100644 --- a/cpukit/libcsupport/src/newlibc.c +++ b/cpukit/libcsupport/src/newlibc_reent.c @@ -1,10 +1,4 @@ /* - * Implementation of hooks for the CYGNUS newlib libc - * These hooks set things up so that: - * + '_REENT' is switched at task switch time. - * - * COPYRIGHT (c) 1994 by Division Incorporated - * * 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. @@ -50,8 +44,7 @@ int _fwalk(struct _reent *ptr, int (*function) (FILE *) ); -extern struct _reent libc_global_reent __ATTRIBUTE_IMPURE_PTR__; - +extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; /* * reent struct allocation moved here from libc_start_hook() to avoid * mutual exclusion problems when memory is allocated from the start hook. @@ -59,13 +52,20 @@ extern struct _reent libc_global_reent __ATTRIBUTE_IMPURE_PTR__; * Memory is also now allocated from the workspace rather than the heap. * -- ptorre 9/30/03 */ -bool libc_create_hook( +bool newlib_create_hook( rtems_tcb *current_task, rtems_tcb *creating_task ) { struct _reent *ptr; + if (_Thread_libc_reent == 0) + { + _REENT = _global_impure_ptr; + + _Thread_Set_libc_reent (&_REENT); + } + /* NOTE: The RTEMS malloc is reentrant without a reent ptr since * it is based on the Classic API Region Manager. */ @@ -81,13 +81,12 @@ bool libc_create_hook( #endif if (ptr) { - - _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */ - creating_task->libc_reent = ptr; - return true; + _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */ + creating_task->libc_reent = ptr; + return TRUE; } - else - return false; + + return FALSE; } /* @@ -95,7 +94,7 @@ bool libc_create_hook( */ #ifdef NEED_SETVBUF -rtems_extension libc_begin_hook(rtems_tcb *current_task) +rtems_extension newlib_begin_hook(rtems_tcb *current_task) { setvbuf( stdout, NULL, _IOLBF, BUFSIZ ); } @@ -128,7 +127,7 @@ int newlib_free_buffers( return 0; } -rtems_extension libc_delete_hook( +rtems_extension newlib_delete_hook( rtems_tcb *current_task, rtems_tcb *deleted_task ) @@ -145,7 +144,7 @@ rtems_extension libc_delete_hook( ptr = deleted_task->libc_reent; } - if (ptr && ptr != &libc_global_reent) { + if (ptr && ptr != _global_impure_ptr) { /* _wrapup_reent(ptr); _reclaim_reent(ptr); diff --git a/cpukit/libcsupport/src/sync.c b/cpukit/libcsupport/src/sync.c index 14c20cebb3..8db3f62161 100644 --- a/cpukit/libcsupport/src/sync.c +++ b/cpukit/libcsupport/src/sync.c @@ -7,7 +7,7 @@ * fsync() * fdatasync() * - * COPYRIGHT (c) 1989-2003. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -71,10 +71,10 @@ static void sync_per_thread(Thread_Control *t) } /* - * libc_global_reent is not prototyped in any .h files. + * _global_impure_ptr is not prototyped in any .h files. * We have to extern it here. */ -extern struct _reent libc_global_reent; +extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; void sync(void) { @@ -82,7 +82,7 @@ void sync(void) /* * Walk the one used initially by RTEMS. */ - _fwalk(&libc_global_reent, sync_wrapper); + _fwalk(_global_impure_ptr, sync_wrapper); /* * XXX Do we walk the one used globally by newlib? diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am index 83e9347968..fe8562b081 100644 --- a/cpukit/libfs/Makefile.am +++ b/cpukit/libfs/Makefile.am @@ -31,7 +31,13 @@ libimfs_a_SOURCES += src/imfs/imfs_chown.c src/imfs/imfs_config.c \ src/imfs/imfs_debug.c src/imfs/imfs_rmnod.c src/imfs/imfs_symlink.c \ src/imfs/imfs_readlink.c src/imfs/imfs_fdatasync.c src/imfs/imfs_fcntl.c \ src/imfs/ioman.c src/imfs/miniimfs_init.c src/imfs/imfs_load_tar.c \ - src/imfs/imfs.h + src/imfs/imfs.h \ + src/imfs/deviceerrno.c \ + src/devfs/devfs_init.c src/devfs/devfs_eval.c src/devfs/devfs_mknod.c \ + src/devfs/devfs_show.c src/devfs/devfs_node_type.c \ + src/devfs/devopen.c src/devfs/devread.c src/devfs/devwrite.c \ + src/devfs/devclose.c src/devfs/devioctl.c src/devfs/devstat.c \ + src/devfs/devfs.h endif # dosfs diff --git a/cpukit/libfs/src/devfs/devclose.c b/cpukit/libfs/src/devfs/devclose.c new file mode 100644 index 0000000000..a87e12f338 --- /dev/null +++ b/cpukit/libfs/src/devfs/devclose.c @@ -0,0 +1,43 @@ +/* + * 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_driver_name_t *np; + + np = (rtems_device_name_t *)iop->file_info; + + args.iop = iop; + args.flags = 0; + args.mode = 0; + + status = rtems_io_close( + np->major, + np->minor, + (void *) &args + ); + if ( status ) { + return rtems_deviceio_errno(status); + } + return 0; +} + + diff --git a/cpukit/libfs/src/devfs/devfs.h b/cpukit/libfs/src/devfs/devfs.h new file mode 100644 index 0000000000..ea3b965bbc --- /dev/null +++ b/cpukit/libfs/src/devfs/devfs.h @@ -0,0 +1,294 @@ +/** +* @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 + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/libio_.h> + +/** + * This structure define the type of device table + */ + +typedef struct +{ + /** This member pointes 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; + + +/** + * 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; + + +/** + * 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 + */ + +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 + */ + + +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. + */ + +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. + */ + +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. + */ + +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. + */ + +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 + */ + +int 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 + */ + +int devFS_evaluate_path( + const char *pathname, + 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 + */ + +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 + */ + +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 temp_mt_entry + * @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. + */ + +int devFS_initialize( + rtems_filesystem_mount_table_entry_t *temp_mt_entry +); + + +/** + * 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. + * + * @param none + * @retval 0 + */ + +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..8f7fb90c87 --- /dev/null +++ b/cpukit/libfs/src/devfs/devfs_eval.c @@ -0,0 +1,65 @@ +/* + * 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" + +int devFS_evaluate_path( + const char *pathname, + 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 ) ) { + assert( 0 ); + rtems_set_errno_and_return_minus_one( EIO ); + } + + /* 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) && + (strcmp(device_name_table[i].device_name, pathname) == 0)){ + /* 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; + 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..e54eaa654a --- /dev/null +++ b/cpukit/libfs/src/devfs/devfs_init.c @@ -0,0 +1,87 @@ +/* + * 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 <stdlib.h> +#include "devfs.h" + +rtems_filesystem_operations_table devFS_ops = +{ + devFS_evaluate_path, + devFS_evaluate_for_make, + NULL, + NULL, + devFS_node_type, + devFS_mknod, + NULL, + NULL, + NULL, + devFS_initialize, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + +rtems_filesystem_file_handlers_r devFS_file_handlers = +{ + devFS_open, + devFS_close, + devFS_read, + devFS_write, + devFS_ioctl, + NULL, + devFS_stat, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + + +int devFS_initialize( + rtems_filesystem_mount_table_entry_t *temp_mt_entry +) +{ + 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..6757877efc --- /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..37b7052459 --- /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" + +int 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..026e3e4d69 --- /dev/null +++ b/cpukit/libfs/src/devfs/devfs_show.c @@ -0,0 +1,35 @@ +/* + * 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" + +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..9f3ec47e41 --- /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_driver_name_t *np; + + np = (rtems_device_name_t *)iop->file_info; + + 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..db9a9a7aec --- /dev/null +++ b/cpukit/libfs/src/devfs/devopen.c @@ -0,0 +1,44 @@ +/* + * 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_driver_name_t *np; + + np = (rtems_device_name_t *)iop->file_info; + + args.iop = iop; + args.flags = iop->flags; + args.mode = mode; + + status = rtems_io_open( + np->major, + np->minor, + (void *) &args + ); + if ( status ) + return rtems_deviceio_errno(status); + + return 0; +} diff --git a/cpukit/libfs/src/devfs/devread.c b/cpukit/libfs/src/devfs/devread.c new file mode 100644 index 0000000000..d532ba3d33 --- /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_driver_name_t *np; + + np = (rtems_device_name_t *)iop->file_info; + + 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..6c6ee3e6b1 --- /dev/null +++ b/cpukit/libfs/src/devfs/devstat.c @@ -0,0 +1,40 @@ +/* + * 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; + if (!the_dev) + rtems_set_errno_and_return_minus_one( EFAULT ); + + buf->st_dev = 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..bc0822251c --- /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_driver_name_t *np; + + np = (rtems_device_name_t *)iop->file_info; + + 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; +} + diff --git a/cpukit/libfs/src/imfs/deviceerrno.c b/cpukit/libfs/src/imfs/deviceerrno.c new file mode 100644 index 0000000000..9a3251f7c5 --- /dev/null +++ b/cpukit/libfs/src/imfs/deviceerrno.c @@ -0,0 +1,57 @@ +/* + * IMFS Device Node Handlers + * + * This file contains the set of handlers used to map operations on + * IMFS device nodes onto calls to the RTEMS Classic API IO Manager. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * 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/libio.h> +#include <rtems/assoc.h> /* assoc.h not included by rtems.h */ +#include <errno.h> + +/* + * Convert RTEMS status to a UNIX errno + */ + +const rtems_assoc_t errno_assoc[] = { + { "OK", RTEMS_SUCCESSFUL, 0 }, + { "BUSY", RTEMS_RESOURCE_IN_USE, EBUSY }, + { "INVALID NAME", RTEMS_INVALID_NAME, EINVAL }, + { "NOT IMPLEMENTED", RTEMS_NOT_IMPLEMENTED, ENOSYS }, + { "TIMEOUT", RTEMS_TIMEOUT, ETIMEDOUT }, + { "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM }, + { "NO DEVICE", RTEMS_UNSATISFIED, ENODEV }, + { "INVALID NUMBER", RTEMS_INVALID_NUMBER, EBADF}, + { "NOT RESOURCE OWNER", RTEMS_NOT_OWNER_OF_RESOURCE, EPERM}, + { "IO ERROR", RTEMS_IO_ERROR, EIO}, + { 0, 0, 0 }, +}; + +int +rtems_deviceio_errno(rtems_status_code code) +{ + int rc; + + if ((rc = rtems_assoc_remote_by_local(errno_assoc, (uint32_t ) code))) + { + errno = rc; + return -1; + } + return -1; +} + + diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c index 5d8c383b89..6bf46066e2 100644 --- a/cpukit/libfs/src/imfs/deviceio.c +++ b/cpukit/libfs/src/imfs/deviceio.c @@ -4,7 +4,7 @@ * This file contains the set of handlers used to map operations on * IMFS device nodes onto calls to the RTEMS Classic API IO Manager. * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/preinstall.am b/cpukit/preinstall.am index 7c5cc69b3f..3977050929 100644 --- a/cpukit/preinstall.am +++ b/cpukit/preinstall.am @@ -146,6 +146,10 @@ $(PROJECT_INCLUDE)/rtems/imfs.h: libfs/src/imfs/imfs.h $(PROJECT_INCLUDE)/rtems/ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/imfs.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/imfs.h +$(PROJECT_INCLUDE)/rtems/devfs.h: libfs/src/devfs/devfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/devfs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/devfs.h + if LIBDOSFS $(PROJECT_INCLUDE)/rtems/dosfs.h: libfs/src/dosfs/dosfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/dosfs.h diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index acc03b7434..aeb149fc6a 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -72,6 +72,37 @@ extern rtems_configuration_table Configuration; #define CONFIGURE_NEWLIB_EXTENSION 0 #endif + +#include <rtems/libio.h> + +#ifdef CONFIGURE_INIT +rtems_libio_init_functions_t rtems_libio_init_helper = + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + NULL; + #else + rtems_libio_init; + #endif + +rtems_libio_supp_functions_t rtems_libio_supp_helper = + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + NULL; + #else + open_dev_console; + #endif + +rtems_fs_init_functions_t rtems_fs_init_helper = + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + NULL; + #else + rtems_filesystem_initialize; + #endif +#endif + + +#ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + #define CONFIGURE_HAS_OWN_MOUNT_TABLE +#endif + /** * This macro defines the number of POSIX file descriptors allocated * and managed by libio. These are the "integer" file descriptors that @@ -138,6 +169,22 @@ extern rtems_configuration_table Configuration; extern int rtems_telnetd_maximum_ptys; #endif +#ifdef CONFIGURE_INIT + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + extern uint32_t rtems_device_table_size; + #define CONFIGURE_MEMORY_FOR_DEVFS 0 + #elif defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM) + #ifndef CONFIGURE_MAXIMUM_DEVICES + #define CONFIGURE_MAXIMUM_DEVICES 4 + #endif + #include <rtems/devfs.h> + uint32_t rtems_device_table_size = CONFIGURE_MAXIMUM_DEVICES; + #define CONFIGURE_MEMORY_FOR_DEVFS _Configure_Object_RAM(CONFIGURE_MAXIMUM_DEVICES, sizeof (rtems_device_name_t)) + #else + #define CONFIGURE_MEMORY_FOR_DEVFS 0 + #endif +#endif + /* * Mount Table Configuration */ @@ -162,6 +209,8 @@ extern rtems_configuration_table Configuration; const rtems_filesystem_mount_table_t configuration_mount_table = { #ifdef CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM &IMFS_ops, + #elif defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM) + &devFS_ops, #else /* using miniIMFS as base filesystem */ &miniIMFS_ops, #endif @@ -574,16 +623,6 @@ extern rtems_configuration_table Configuration; #define CONFIGURE_MAXIMUM_DRIVERS CONFIGURE_NUMBER_OF_DRIVERS #endif -/** - * Default the number of devices per device driver. This value may be - * overridden by the user. - * - * @note This configuration parameter is obsolete. Thus we will warn the - * user that it is obsolete. - */ -#ifdef CONFIGURE_MAXIMUM_DEVICES - #warning "CONFIGURE_MAXIMUM_DEVICES is obsolete. Do not use any longer." -#endif #ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER /* @@ -1681,6 +1720,7 @@ extern rtems_configuration_table Configuration; #define CONFIGURE_EXECUTIVE_RAM_SIZE \ (( \ CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD + \ + CONFIGURE_MEMORY_FOR_DEVFS + \ CONFIGURE_MEMORY_FOR_TASKS( \ CONFIGURE_TOTAL_TASKS_AND_THREADS, CONFIGURE_TOTAL_TASKS_AND_THREADS) + \ CONFIGURE_MEMORY_FOR_CLASSIC + \ |