[rtems commit] termios: Use IMFS nodes for new Termios devices

Sebastian Huber sebh at rtems.org
Mon Sep 19 05:53:55 UTC 2016


Module:    rtems
Branch:    master
Commit:    55e0be36069942e0343e406615a3b1744cf7d6b3
Changeset: http://git.rtems.org/rtems/commit/?id=55e0be36069942e0343e406615a3b1744cf7d6b3

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Sep 16 12:58:06 2016 +0200

termios: Use IMFS nodes for new Termios devices

This makes the new Termios devices independent of device major/minor
numbers.  It enables BSP independent Termios device drivers which may
reside in the cpukit domain.  These drivers require an IMFS and do not
work with the device file system.  However, the device file system
should go away in the future.

---

 c/src/lib/libbsp/arm/atsam/console/console.c       |  14 +-
 c/src/lib/libbsp/arm/tms570/console/tms570-sci.c   |   2 -
 c/src/lib/libbsp/powerpc/t32mppc/console/console.c |   2 -
 c/src/lib/libbsp/shared/console-termios-init.c     |  41 +-
 c/src/lib/libbsp/shared/console-termios.c          |  20 +-
 c/src/lib/libbsp/shared/include/console-termios.h  |  19 -
 c/src/lib/libbsp/sparc/leon3/console/console.c     |   6 -
 cpukit/libcsupport/include/rtems/termiostypes.h    |  56 +--
 cpukit/libcsupport/src/termios.c                   | 460 +++++++++++++--------
 testsuites/libtests/termios01/init.c               | 162 +++-----
 testsuites/psxtests/psxfile01/test.c               |   3 +-
 11 files changed, 350 insertions(+), 435 deletions(-)

diff --git a/c/src/lib/libbsp/arm/atsam/console/console.c b/c/src/lib/libbsp/arm/atsam/console/console.c
index ef75e8c..ebf284b 100644
--- a/c/src/lib/libbsp/arm/atsam/console/console.c
+++ b/c/src/lib/libbsp/arm/atsam/console/console.c
@@ -21,6 +21,8 @@
 
 #include <chip.h>
 
+#include <unistd.h>
+
 typedef struct {
   rtems_termios_device_context base;
   Usart *regs;
@@ -488,8 +490,6 @@ rtems_status_code console_initialize(
     usart[sizeof(usart) - 2] = (char) ('0' + i);
     rtems_termios_device_install(
       &usart[0],
-      major,
-      minor,
       &atsam_usart_handler,
       NULL,
       &atsam_usart_instances[i].base
@@ -498,11 +498,9 @@ rtems_status_code console_initialize(
 #if ATSAM_CONSOLE_DEVICE_TYPE == 0
     if (i == ATSAM_CONSOLE_DEVICE_INDEX) {
       atsam_usart_instances[i].console = true;
-      rtems_io_register_name(CONSOLE_DEVICE_NAME, major, minor);
+      link(&usart[0], CONSOLE_DEVICE_NAME);
     }
 #endif
-
-    ++minor;
   }
 
   for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_uart_instances); ++i) {
@@ -511,8 +509,6 @@ rtems_status_code console_initialize(
     uart[sizeof(uart) - 2] = (char) ('0' + i);
     rtems_termios_device_install(
       &uart[0],
-      major,
-      minor,
       &atsam_uart_handler,
       NULL,
       &atsam_uart_instances[i].base
@@ -521,11 +517,9 @@ rtems_status_code console_initialize(
 #if ATSAM_CONSOLE_DEVICE_TYPE == 1
     if (i == ATSAM_CONSOLE_DEVICE_INDEX) {
       atsam_uart_instances[i].console = true;
-      rtems_io_register_name(CONSOLE_DEVICE_NAME, major, minor);
+      link(&usart[0], CONSOLE_DEVICE_NAME);
     }
 #endif
-
-    ++minor;
   }
 
   return RTEMS_SUCCESSFUL;
diff --git a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
index 6651cd8..1cd3fe1 100644
--- a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
+++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
@@ -138,8 +138,6 @@ rtems_device_driver console_initialize(
      */
     sc = rtems_termios_device_install(
         ctx->device_name,
-        major,
-        minor,
         handler,
         NULL,
         &ctx->base
diff --git a/c/src/lib/libbsp/powerpc/t32mppc/console/console.c b/c/src/lib/libbsp/powerpc/t32mppc/console/console.c
index 0c39bdd..bc94f85 100644
--- a/c/src/lib/libbsp/powerpc/t32mppc/console/console.c
+++ b/c/src/lib/libbsp/powerpc/t32mppc/console/console.c
@@ -115,8 +115,6 @@ rtems_device_driver console_initialize(
   rtems_termios_device_context_initialize(&ctx->base, "T32 Console");
   rtems_termios_device_install(
     CONSOLE_DEVICE_NAME,
-    major,
-    0,
     &t32_console_handler,
     NULL,
     &ctx->base
diff --git a/c/src/lib/libbsp/shared/console-termios-init.c b/c/src/lib/libbsp/shared/console-termios-init.c
index 83d14d1..a01a75a 100644
--- a/c/src/lib/libbsp/shared/console-termios-init.c
+++ b/c/src/lib/libbsp/shared/console-termios-init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -17,36 +17,7 @@
 
 #include <rtems/console.h>
 
-RTEMS_INTERRUPT_LOCK_DEFINE( static, console_lock, "console" )
-
-static rtems_device_major_number console_major = UINT32_MAX;
-
-static rtems_device_minor_number console_minor;
-
-rtems_status_code console_device_install(
-  const char                         *device_file,
-  const rtems_termios_device_handler *handler,
-  const rtems_termios_device_flow    *flow,
-  rtems_termios_device_context       *context
-)
-{
-  rtems_interrupt_lock_context lock_context;
-  rtems_device_minor_number    minor;
-
-  rtems_interrupt_lock_acquire( &console_lock, &lock_context );
-  minor = console_minor;
-  ++console_minor;
-  rtems_interrupt_lock_release( &console_lock, &lock_context );
-
-  return rtems_termios_device_install(
-    device_file,
-    console_major,
-    minor,
-    handler,
-    flow,
-    context
-  );
-}
+#include <unistd.h>
 
 bool console_device_probe_default(rtems_termios_device_context *context)
 {
@@ -72,8 +43,6 @@ rtems_device_driver console_initialize(
     if ( ( *ctx->probe )( ctx->context ) ) {
       sc = rtems_termios_device_install(
         ctx->device_file,
-        major,
-        minor,
         ctx->handler,
         ctx->flow,
         ctx->context
@@ -85,16 +54,12 @@ rtems_device_driver console_initialize(
       if ( !console_device_done ) {
         console_device_done = true;
 
-        sc = rtems_io_register_name( CONSOLE_DEVICE_NAME, major, minor );
-        if ( sc != RTEMS_SUCCESSFUL ) {
+        if ( link( ctx->device_file, CONSOLE_DEVICE_NAME ) != 0 ) {
           bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_1 );
         }
       }
     }
   }
 
-  console_major = major;
-  console_minor = minor;
-
   return RTEMS_SUCCESSFUL;
 }
diff --git a/c/src/lib/libbsp/shared/console-termios.c b/c/src/lib/libbsp/shared/console-termios.c
index f57b06c..1e755d9 100644
--- a/c/src/lib/libbsp/shared/console-termios.c
+++ b/c/src/lib/libbsp/shared/console-termios.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -21,7 +21,11 @@ rtems_device_driver console_open(
   void                      *arg
 )
 {
-  return rtems_termios_device_open( major, minor, arg );
+  (void) major;
+  (void) minor;
+  (void) arg;
+
+  return RTEMS_INTERNAL_ERROR;
 }
 
 rtems_device_driver console_close(
@@ -32,8 +36,9 @@ rtems_device_driver console_close(
 {
   (void) major;
   (void) minor;
+  (void) arg;
 
-  return rtems_termios_device_close( arg );
+  return RTEMS_INTERNAL_ERROR;
 }
 
 rtems_device_driver console_read(
@@ -44,8 +49,9 @@ rtems_device_driver console_read(
 {
   (void) major;
   (void) minor;
+  (void) arg;
 
-  return rtems_termios_read( arg );
+  return RTEMS_INTERNAL_ERROR;
 }
 
 rtems_device_driver console_write(
@@ -56,8 +62,9 @@ rtems_device_driver console_write(
 {
   (void) major;
   (void) minor;
+  (void) arg;
 
-  return rtems_termios_write( arg );
+  return RTEMS_INTERNAL_ERROR;
 }
 
 rtems_device_driver console_control(
@@ -68,6 +75,7 @@ rtems_device_driver console_control(
 {
   (void) major;
   (void) minor;
+  (void) arg;
 
-  return rtems_termios_ioctl( arg );
+  return RTEMS_INTERNAL_ERROR;
 }
diff --git a/c/src/lib/libbsp/shared/include/console-termios.h b/c/src/lib/libbsp/shared/include/console-termios.h
index bbb9f35..413dde4 100644
--- a/c/src/lib/libbsp/shared/include/console-termios.h
+++ b/c/src/lib/libbsp/shared/include/console-termios.h
@@ -87,25 +87,6 @@ typedef struct {
 } console_device;
 
 /**
- * @brief Installs a console device after console driver initialization.
- *
- * @param[in] device_file The device file path.
- * @param[in] handler The Termios device handler.  It must be persistent
- *   throughout the installed time of the device.
- * @param[in] flow The Termios device flow control handler.  The device flow
- *   control handler are optional and may be @c NULL.  If present must be
- *   persistent throughout the installed time of the device.
- * @param[in] context The Termios device context.  It must be persistent
- *   throughout the installed time of the device.
- */
-rtems_status_code console_device_install(
-  const char                         *device_file,
-  const rtems_termios_device_handler *handler,
-  const rtems_termios_device_flow    *flow,
-  rtems_termios_device_context       *context
-);
-
-/**
  * @brief Returns true and does nothing else.
  */
 bool console_device_probe_default(rtems_termios_device_context *context);
diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c
index eba0013..666069e 100644
--- a/c/src/lib/libbsp/sparc/leon3/console/console.c
+++ b/c/src/lib/libbsp/sparc/leon3/console/console.c
@@ -131,11 +131,8 @@ rtems_device_driver console_initialize(
    * On a MP system one should not open UARTs that other OS instances use.
    */
   if (syscon_uart_index < uarts) {
-    minor = 0;
     status = rtems_termios_device_install(
       CONSOLE_DEVICE_NAME,
-      major,
-      minor,
       handler,
       NULL,
       leon3_console_get_context(syscon_uart_index)
@@ -148,11 +145,8 @@ rtems_device_driver console_initialize(
     if (i == syscon_uart_index)
       continue; /* skip UART that is registered as /dev/console */
     console_name[13] = 'a' + i;
-    minor = i + 1;
     rtems_termios_device_install(
       console_name,
-      major,
-      minor,
       handler,
       NULL,
       leon3_console_get_context(i)
diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
index 71be95f..80251a2 100644
--- a/cpukit/libcsupport/include/rtems/termiostypes.h
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -344,10 +344,9 @@ typedef struct rtems_termios_tty {
 /**
  * @brief Installs a Termios device.
  *
- * @param[in] device_file If not @c NULL, then a device file for the specified
- *   major and minor number will be created.
- * @param[in] major The device major number of the corresponding device driver.
- * @param[in] minor The device minor number of the corresponding device driver.
+ * The installed Termios device may be removed via unlink().
+ *
+ * @param[in] device_file The device file path.
  * @param[in] handler The device handler.  It must be persistent throughout the
  *   installed time of the device.
  * @param[in] flow The device flow control handler.  The device flow control
@@ -359,65 +358,18 @@ typedef struct rtems_termios_tty {
  * @retval RTEMS_SUCCESSFUL Successful operation.
  * @retval RTEMS_NO_MEMORY Not enough memory to create a device node.
  * @retval RTEMS_UNSATISFIED Creation of the device file failed.
- * @retval RTEMS_RESOURCE_IN_USE There exists a device node for this major and
- *   minor number pair.
  * @retval RTEMS_INCORRECT_STATE Termios is not initialized.
  *
- * @see rtems_termios_device_remove(), rtems_termios_device_open(),
- *   rtems_termios_device_close() and rtems_termios_get_device_context().
+ * @see rtems_termios_get_device_context().
  */
 rtems_status_code rtems_termios_device_install(
   const char                         *device_file,
-  rtems_device_major_number           major,
-  rtems_device_minor_number           minor,
   const rtems_termios_device_handler *handler,
   const rtems_termios_device_flow    *flow,
   rtems_termios_device_context       *context
 );
 
 /**
- * @brief Removes a Termios device.
- *
- * @param[in] device_file If not @c NULL, then the device file to remove.
- * @param[in] major The device major number of the corresponding device driver.
- * @param[in] minor The device minor number of the corresponding device driver.
- *
- * @retval RTEMS_SUCCESSFUL Successful operation.
- * @retval RTEMS_INVALID_ID There is no device installed with this major and
- * minor number pair.
- * @retval RTEMS_RESOURCE_IN_USE This device is currently in use.
- * @retval RTEMS_UNSATISFIED Removal of the device file failed.
- * @retval RTEMS_INCORRECT_STATE Termios is not initialized.
- *
- * @see rtems_termios_device_install().
- */
-rtems_status_code rtems_termios_device_remove(
-  const char                *device_file,
-  rtems_device_major_number  major,
-  rtems_device_minor_number  minor
-);
-
-/**
- * @brief Opens an installed Termios device.
- *
- * @see rtems_termios_device_install().
- */
-rtems_status_code rtems_termios_device_open(
-  rtems_device_major_number  major,
-  rtems_device_minor_number  minor,
-  void                      *arg
-);
-
-/**
- * @brief Closes an installed Termios device.
- *
- * @retval RTEMS_SUCCESSFUL Successful operation.
- *
- * @see rtems_termios_device_install().
- */
-rtems_status_code rtems_termios_device_close(void *arg);
-
-/**
  * @brief Returns the device context of an installed Termios device.
  *
  * @param[in] tty The Termios control.
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index d9886f4..3a6a389 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -22,6 +22,8 @@
 
 #include <rtems.h>
 #include <rtems/libio.h>
+#include <rtems/imfs.h>
+#include <rtems/score/assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
@@ -85,6 +87,8 @@ static size_t rtems_termios_cbufsize = 256;
 static size_t rtems_termios_raw_input_size = 128;
 static size_t rtems_termios_raw_output_size = 64;
 
+static const IMFS_node_control rtems_termios_imfs_node_control;
+
 static struct rtems_termios_tty *rtems_termios_ttyHead;
 static struct rtems_termios_tty *rtems_termios_ttyTail;
 
@@ -108,126 +112,55 @@ static rtems_task rtems_termios_txdaemon(rtems_task_argument argument);
 #define TERMIOS_RX_PROC_EVENT      RTEMS_EVENT_1
 #define TERMIOS_RX_TERMINATE_EVENT RTEMS_EVENT_0
 
-static rtems_termios_device_node *
-rtems_termios_find_device_node(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor
-)
+static rtems_status_code
+rtems_termios_obtain (void)
 {
-  rtems_chain_node *tail = rtems_chain_tail(&rtems_termios_devices);
-  rtems_chain_node *current = rtems_chain_first(&rtems_termios_devices);
-
-  while (current != tail) {
-    rtems_termios_device_node *device_node =
-      (rtems_termios_device_node *) current;
-
-    if (device_node->major == major && device_node->minor == minor) {
-      return device_node;
-    }
+  return rtems_semaphore_obtain (rtems_termios_ttyMutex, RTEMS_WAIT,
+    RTEMS_NO_TIMEOUT);
+}
 
-    current = rtems_chain_next(current);
-  }
+static void
+rtems_termios_release (void)
+{
+  rtems_status_code sc;
 
-  return NULL;
+  sc = rtems_semaphore_release (rtems_termios_ttyMutex);
+  _Assert (sc == RTEMS_SUCCESSFUL);
+  (void) sc;
 }
 
 rtems_status_code rtems_termios_device_install(
   const char                         *device_file,
-  rtems_device_major_number           major,
-  rtems_device_minor_number           minor,
   const rtems_termios_device_handler *handler,
   const rtems_termios_device_flow    *flow,
   rtems_termios_device_context       *context
 )
 {
-  rtems_status_code          sc;
   rtems_termios_device_node *new_device_node;
-  rtems_termios_device_node *existing_device_node;
+  int rv;
 
-  new_device_node = malloc(sizeof(*new_device_node));
+  new_device_node = calloc (1, sizeof(*new_device_node));
   if (new_device_node == NULL) {
     return RTEMS_NO_MEMORY;
   }
 
-  rtems_chain_initialize_node(&new_device_node->node);
-  new_device_node->major = major;
-  new_device_node->minor = minor;
+  rtems_chain_initialize_node (&new_device_node->node);
   new_device_node->handler = handler;
   new_device_node->flow = flow;
   new_device_node->context = context;
   new_device_node->tty = NULL;
 
-  sc = rtems_semaphore_obtain(
-    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-  if (sc != RTEMS_SUCCESSFUL) {
-    free(new_device_node);
-    return RTEMS_INCORRECT_STATE;
-  }
-
-  existing_device_node = rtems_termios_find_device_node (major, minor);
-  if (existing_device_node != NULL) {
-    free(new_device_node);
-    rtems_semaphore_release (rtems_termios_ttyMutex);
-    return RTEMS_RESOURCE_IN_USE;
-  }
-
-  if (device_file != NULL) {
-    sc = rtems_io_register_name (device_file, major, minor);
-    if (sc != RTEMS_SUCCESSFUL) {
-      free(new_device_node);
-      rtems_semaphore_release (rtems_termios_ttyMutex);
-      return RTEMS_UNSATISFIED;
-    }
-  }
-
-  rtems_chain_append_unprotected(
-    &rtems_termios_devices, &new_device_node->node);
-
-  rtems_semaphore_release (rtems_termios_ttyMutex);
-
-  return RTEMS_SUCCESSFUL;
-}
-
-rtems_status_code rtems_termios_device_remove(
-  const char                *device_file,
-  rtems_device_major_number  major,
-  rtems_device_minor_number  minor
-)
-{
-  rtems_status_code          sc;
-  rtems_termios_device_node *device_node;
-
-  sc = rtems_semaphore_obtain(
-    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-  if (sc != RTEMS_SUCCESSFUL) {
-    return RTEMS_INCORRECT_STATE;
-  }
-
-  device_node = rtems_termios_find_device_node (major, minor);
-  if (device_node == NULL) {
-    rtems_semaphore_release (rtems_termios_ttyMutex);
-    return RTEMS_INVALID_ID;
-  }
-
-  if (device_node->tty != NULL) {
-    rtems_semaphore_release (rtems_termios_ttyMutex);
-    return RTEMS_RESOURCE_IN_USE;
-  }
-
-  if (device_file != NULL) {
-    int rv = unlink (device_file);
-
-    if (rv != 0) {
-      rtems_semaphore_release (rtems_termios_ttyMutex);
-      return RTEMS_UNSATISFIED;
-    }
+  rv = IMFS_make_generic_node(
+    device_file,
+    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &rtems_termios_imfs_node_control,
+    new_device_node
+  );
+  if (rv != 0) {
+    free (new_device_node);
+    return RTEMS_UNSATISFIED;
   }
 
-  rtems_chain_extract_unprotected (&device_node->node);
-  free (device_node);
-
-  rtems_semaphore_release (rtems_termios_ttyMutex);
-
   return RTEMS_SUCCESSFUL;
 }
 
@@ -629,40 +562,6 @@ rtems_termios_open_tty(
   return tty;
 }
 
-rtems_status_code
-rtems_termios_device_open(
-  rtems_device_major_number  major,
-  rtems_device_minor_number  minor,
-  void                      *arg
-)
-{
-  rtems_status_code          sc;
-  rtems_termios_device_node *device_node;
-  struct rtems_termios_tty  *tty;
-
-  sc = rtems_semaphore_obtain(
-    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-  if (sc != RTEMS_SUCCESSFUL)
-    return sc;
-
-  device_node = rtems_termios_find_device_node (major, minor);
-  if (device_node == NULL) {
-    rtems_semaphore_release (rtems_termios_ttyMutex);
-    return RTEMS_INVALID_ID;
-  }
-
-  tty = rtems_termios_open_tty(
-    major, minor, arg, device_node->tty, device_node, NULL);
-  if (tty == NULL) {
-    rtems_semaphore_release (rtems_termios_ttyMutex);
-    return RTEMS_NO_MEMORY;
-  }
-
-  rtems_semaphore_release (rtems_termios_ttyMutex);
-
-  return RTEMS_SUCCESSFUL;
-}
-
 /*
  * Open a termios device
  */
@@ -680,8 +579,7 @@ rtems_termios_open (
   /*
    * See if the device has already been opened
    */
-  sc = rtems_semaphore_obtain(
-    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  sc = rtems_termios_obtain ();
   if (sc != RTEMS_SUCCESSFUL)
     return sc;
 
@@ -693,7 +591,7 @@ rtems_termios_open (
   tty = rtems_termios_open_tty(
     major, minor, arg, tty, NULL, callbacks);
   if (tty == NULL) {
-    rtems_semaphore_release (rtems_termios_ttyMutex);
+    rtems_termios_release ();
     return RTEMS_NO_MEMORY;
   }
 
@@ -710,7 +608,7 @@ rtems_termios_open (
       rtems_termios_ttyTail = tty;
   }
 
-  rtems_semaphore_release (rtems_termios_ttyMutex);
+  rtems_termios_release ();
 
   return RTEMS_SUCCESSFUL;
 }
@@ -755,8 +653,7 @@ rtems_termios_close (void *arg)
   rtems_libio_open_close_args_t *args = arg;
   struct rtems_termios_tty *tty = args->iop->data1;
 
-  sc = rtems_semaphore_obtain(
-    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  sc = rtems_termios_obtain ();
   if (sc != RTEMS_SUCCESSFUL)
     rtems_fatal_error_occurred (sc);
 
@@ -782,26 +679,7 @@ rtems_termios_close (void *arg)
 
   rtems_termios_close_tty (tty, arg);
 
-  rtems_semaphore_release (rtems_termios_ttyMutex);
-
-  return RTEMS_SUCCESSFUL;
-}
-
-rtems_status_code
-rtems_termios_device_close (void *arg)
-{
-  rtems_status_code sc;
-  rtems_libio_open_close_args_t *args = arg;
-  struct rtems_termios_tty *tty = args->iop->data1;
-
-  sc = rtems_semaphore_obtain(
-    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-  if (sc != RTEMS_SUCCESSFUL)
-    rtems_fatal_error_occurred (sc);
-
-  rtems_termios_close_tty (tty, arg);
-
-  rtems_semaphore_release (rtems_termios_ttyMutex);
+  rtems_termios_release ();
 
   return RTEMS_SUCCESSFUL;
 }
@@ -1193,6 +1071,25 @@ oproc (unsigned char c, struct rtems_termios_tty *tty)
   rtems_termios_puts (&c, 1, tty);
 }
 
+static uint32_t
+rtems_termios_write_tty (struct rtems_termios_tty *tty, const char *buffer,
+  uint32_t initial_count)
+{
+
+  if (tty->termios.c_oflag & OPOST) {
+    uint32_t count;
+
+    count = initial_count;
+
+    while (count--)
+      oproc (*buffer++, tty);
+  } else {
+    rtems_termios_puts (buffer, initial_count, tty);
+  }
+
+  return initial_count;
+}
+
 rtems_status_code
 rtems_termios_write (void *arg)
 {
@@ -1208,16 +1105,7 @@ rtems_termios_write (void *arg)
     rtems_semaphore_release (tty->osem);
     return sc;
   }
-  if (tty->termios.c_oflag & OPOST) {
-    uint32_t   count = args->count;
-    char      *buffer = args->buffer;
-    while (count--)
-      oproc (*buffer++, tty);
-    args->bytes_moved = args->count;
-  } else {
-    rtems_termios_puts (args->buffer, args->count, tty);
-    args->bytes_moved = args->count;
-  }
+  args->bytes_moved = rtems_termios_write_tty (tty, args->buffer, args->count);
   rtems_semaphore_release (tty->osem);
   return sc;
 }
@@ -1521,27 +1409,17 @@ fillBufferQueue (struct rtems_termios_tty *tty)
   return RTEMS_SUCCESSFUL;
 }
 
-rtems_status_code
-rtems_termios_read (void *arg)
+static uint32_t
+rtems_termios_read_tty (struct rtems_termios_tty *tty, char *buffer,
+  uint32_t initial_count)
 {
-  rtems_libio_rw_args_t *args = arg;
-  struct rtems_termios_tty *tty = args->iop->data1;
-  uint32_t   count = args->count;
-  char      *buffer = args->buffer;
-  rtems_status_code sc;
-
-  sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-  if (sc != RTEMS_SUCCESSFUL)
-    return sc;
+  uint32_t count;
 
-  if (rtems_termios_linesw[tty->t_line].l_read != NULL) {
-    sc = rtems_termios_linesw[tty->t_line].l_read(tty,args);
-    tty->tty_rcvwakeup = 0;
-    rtems_semaphore_release (tty->isem);
-    return sc;
-  }
+  count = initial_count;
 
   if (tty->cindex == tty->ccount) {
+    rtems_status_code sc;
+
     tty->cindex = tty->ccount = 0;
     tty->read_start_column = tty->column;
     if (tty->handler.poll_read != NULL && tty->handler.mode == TERMIOS_POLLED)
@@ -1556,8 +1434,29 @@ rtems_termios_read (void *arg)
     *buffer++ = tty->cbuf[tty->cindex++];
     count--;
   }
-  args->bytes_moved = args->count - count;
   tty->tty_rcvwakeup = 0;
+  return initial_count - count;
+}
+
+rtems_status_code
+rtems_termios_read (void *arg)
+{
+  rtems_libio_rw_args_t *args = arg;
+  struct rtems_termios_tty *tty = args->iop->data1;
+  rtems_status_code sc;
+
+  sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  if (sc != RTEMS_SUCCESSFUL)
+    return sc;
+
+  if (rtems_termios_linesw[tty->t_line].l_read != NULL) {
+    sc = rtems_termios_linesw[tty->t_line].l_read(tty,args);
+    tty->tty_rcvwakeup = 0;
+    rtems_semaphore_release (tty->isem);
+    return sc;
+  }
+
+  args->bytes_moved = rtems_termios_read_tty (tty, args->buffer, args->count);
   rtems_semaphore_release (tty->isem);
   return sc;
 }
@@ -1928,3 +1827,198 @@ static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument)
     }
   }
 }
+
+static int
+rtems_termios_imfs_open (rtems_libio_t *iop,
+  const char *path, int oflag, mode_t mode)
+{
+  rtems_termios_device_node *device_node;
+  rtems_status_code sc;
+  rtems_libio_open_close_args_t args;
+  struct rtems_termios_tty *tty;
+
+  device_node = IMFS_generic_get_context_by_iop (iop);
+
+  memset (&args, 0, sizeof (args));
+  args.iop = iop;
+  args.flags = iop->flags;
+  args.mode = mode;
+
+  sc = rtems_termios_obtain ();
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_set_errno_and_return_minus_one (ENXIO);
+  }
+
+  tty = rtems_termios_open_tty (device_node->major, device_node->minor, &args,
+      device_node->tty, device_node, NULL);
+  if (tty == NULL) {
+    rtems_termios_release ();
+    rtems_set_errno_and_return_minus_one (ENOMEM);
+  }
+
+  rtems_termios_release ();
+  return 0;
+}
+
+static int
+rtems_termios_imfs_close (rtems_libio_t *iop)
+{
+  rtems_status_code sc;
+  rtems_libio_open_close_args_t args;
+  struct rtems_termios_tty *tty;
+
+  memset (&args, 0, sizeof (args));
+  args.iop = iop;
+
+  tty = iop->data1;
+
+  sc = rtems_termios_obtain ();
+  _Assert (sc == RTEMS_SUCCESSFUL);
+  (void) sc;
+
+  rtems_termios_close_tty (tty, &args);
+  rtems_termios_release ();
+  return 0;
+}
+
+static ssize_t
+rtems_termios_imfs_read (rtems_libio_t *iop, void *buffer, size_t count)
+{
+  struct rtems_termios_tty *tty;
+  rtems_status_code sc;
+  uint32_t bytes_moved;
+
+  tty = iop->data1;
+
+  sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  _Assert (sc == RTEMS_SUCCESSFUL);
+
+  if (rtems_termios_linesw[tty->t_line].l_read != NULL) {
+    rtems_libio_rw_args_t args;
+
+    memset (&args, 0, sizeof (args));
+    args.iop = iop;
+    args.buffer = buffer;
+    args.count = count;
+    args.flags = iop->flags;
+
+    sc = rtems_termios_linesw[tty->t_line].l_read (tty, &args);
+    tty->tty_rcvwakeup = 0;
+    rtems_semaphore_release (tty->isem);
+
+    if (sc != RTEMS_SUCCESSFUL) {
+      return rtems_status_code_to_errno (sc);
+    }
+
+    return (ssize_t) args.bytes_moved;
+  }
+
+  bytes_moved = rtems_termios_read_tty (tty, buffer, count);
+  rtems_semaphore_release (tty->isem);
+  return (ssize_t) bytes_moved;
+}
+
+static ssize_t
+rtems_termios_imfs_write (rtems_libio_t *iop, const void *buffer, size_t count)
+{
+  struct rtems_termios_tty *tty;
+  rtems_status_code sc;
+  uint32_t bytes_moved;
+
+  tty = iop->data1;
+
+  sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  _Assert (sc == RTEMS_SUCCESSFUL);
+
+  if (rtems_termios_linesw[tty->t_line].l_write != NULL) {
+    rtems_libio_rw_args_t args;
+
+    memset (&args, 0, sizeof (args));
+    args.iop = iop;
+    args.buffer = RTEMS_DECONST (void *, buffer);
+    args.count = count;
+    args.flags = iop->flags;
+
+    sc = rtems_termios_linesw[tty->t_line].l_write (tty, &args);
+    rtems_semaphore_release (tty->osem);
+
+    if (sc != RTEMS_SUCCESSFUL) {
+      return rtems_status_code_to_errno (sc);
+    }
+
+    return (ssize_t) args.bytes_moved;
+  }
+
+  bytes_moved = rtems_termios_write_tty (tty, buffer, count);
+  rtems_semaphore_release (tty->osem);
+  return (ssize_t) bytes_moved;
+}
+
+static int
+rtems_termios_imfs_ioctl (rtems_libio_t *iop, uint32_t request, void *buffer)
+{
+  rtems_status_code sc;
+  rtems_libio_ioctl_args_t args;
+
+  memset (&args, 0, sizeof (args));
+  args.iop = iop;
+  args.command = request;
+  args.buffer = buffer;
+
+  sc = rtems_termios_ioctl (&args);
+  if ( sc == RTEMS_SUCCESSFUL ) {
+    return args.ioctl_return;
+  } else {
+    return rtems_status_code_to_errno (sc);
+  }
+}
+
+static const rtems_filesystem_file_handlers_r rtems_termios_imfs_handler = {
+  .open_h = rtems_termios_imfs_open,
+  .close_h = rtems_termios_imfs_close,
+  .read_h = rtems_termios_imfs_read,
+  .write_h = rtems_termios_imfs_write,
+  .ioctl_h = rtems_termios_imfs_ioctl,
+  .lseek_h = rtems_filesystem_default_lseek,
+  .fstat_h = IMFS_stat,
+  .ftruncate_h = rtems_filesystem_default_ftruncate,
+  .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+  .fcntl_h = rtems_filesystem_default_fcntl,
+  .kqfilter_h = rtems_filesystem_default_kqfilter,
+  .poll_h = rtems_filesystem_default_poll,
+  .readv_h = rtems_filesystem_default_readv,
+  .writev_h = rtems_filesystem_default_writev
+};
+
+static IMFS_jnode_t *
+rtems_termios_imfs_node_initialize (IMFS_jnode_t *node, void *arg)
+{
+  rtems_termios_device_node *device_node;
+  dev_t dev;
+
+  node = IMFS_node_initialize_generic (node, arg);
+  device_node = IMFS_generic_get_context_by_node (node);
+  dev = IMFS_generic_get_device_identifier_by_node (node);
+  device_node->major = rtems_filesystem_dev_major_t (dev);
+  device_node->minor = rtems_filesystem_dev_minor_t (dev);
+
+  return node;
+}
+
+static void
+rtems_termios_imfs_node_destroy (IMFS_jnode_t *node)
+{
+  rtems_termios_device_node *device_node;
+
+  device_node = IMFS_generic_get_context_by_node (node);
+  free (device_node);
+  IMFS_node_destroy_default (node);
+}
+
+static const IMFS_node_control rtems_termios_imfs_node_control =
+  IMFS_GENERIC_INITIALIZER(
+    &rtems_termios_imfs_handler,
+    rtems_termios_imfs_node_initialize,
+    rtems_termios_imfs_node_destroy
+  );
diff --git a/testsuites/libtests/termios01/init.c b/testsuites/libtests/termios01/init.c
index c836b3d..64c3bb2 100644
--- a/testsuites/libtests/termios01/init.c
+++ b/testsuites/libtests/termios01/init.c
@@ -18,7 +18,9 @@
 #include <rtems/termiostypes.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <unistd.h>
 #include <sys/errno.h>
+#include <sys/stat.h>
 
 const char rtems_test_name[] = "TERMIOS 1";
 
@@ -522,22 +524,32 @@ typedef struct {
   bool done;
 } device_context;
 
-static rtems_status_code test_early_device_install_remove(
+static rtems_status_code test_early_device_install(
   rtems_device_major_number major,
   rtems_device_minor_number minor,
   void *arg
 )
 {
+  static const rtems_termios_device_handler handler;
+  static const char dev[] = "/foobar";
+
   rtems_resource_snapshot snapshot;
   rtems_status_code sc;
+  int fd;
+  int rv;
 
   rtems_resource_snapshot_take( &snapshot );
 
-  sc = rtems_termios_device_install( "/", 0, 0, NULL, NULL, NULL );
-  rtems_test_assert( sc == RTEMS_INCORRECT_STATE );
+  sc = rtems_termios_device_install( &dev[0], &handler, NULL, NULL );
+  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+  errno = 0;
+  fd = open( &dev[0], O_RDWR );
+  rtems_test_assert( fd == -1 );
+  rtems_test_assert( errno == ENXIO );
 
-  sc = rtems_termios_device_remove( "/", 0, 0 );
-  rtems_test_assert( sc == RTEMS_INCORRECT_STATE );
+  rv = unlink( &dev[0] );
+  rtems_test_assert( rv == 0 );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 
@@ -547,88 +559,34 @@ static rtems_status_code test_early_device_install_remove(
 static void test_device_install_remove(void)
 {
   static const rtems_termios_device_handler handler;
-  static const rtems_device_major_number major = 123456789;
-  static const rtems_device_minor_number minor = 0xdeadbeef;
   static const char dev[] = "/foobar";
 
   rtems_resource_snapshot snapshot;
   rtems_status_code sc;
   void *greedy;
-  rtems_libio_t iop;
-  rtems_libio_open_close_args_t args;
-
-  memset( &iop, 0, sizeof( iop ) );
-  memset( &args, 0, sizeof( args ) );
-  args.iop = &iop;
+  int rv;
 
   rtems_resource_snapshot_take( &snapshot );
 
   greedy = rtems_heap_greedy_allocate( NULL, 0 );
 
-  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL );
+  sc = rtems_termios_device_install( "/", &handler, NULL, NULL );
   rtems_test_assert( sc == RTEMS_NO_MEMORY );
 
   rtems_heap_greedy_free( greedy );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 
-  sc = rtems_termios_device_install(
-    NULL,
-    major,
-    minor,
-    &handler,
-    NULL,
-    NULL
-  );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
-
-  sc = rtems_termios_device_install(
-    NULL,
-    major,
-    minor,
-    &handler,
-    NULL,
-    NULL
-  );
-  rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE );
-
-  sc = rtems_termios_device_remove( NULL, major, minor );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
-
-  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
-
-  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL );
+  sc = rtems_termios_device_install( "/", &handler, NULL, NULL );
   rtems_test_assert( sc == RTEMS_UNSATISFIED );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 
-  sc = rtems_termios_device_remove( NULL, major, minor );
-  rtems_test_assert( sc == RTEMS_INVALID_ID );
-
-  sc = rtems_termios_device_install(
-    &dev[0],
-    major,
-    minor,
-    &handler,
-    NULL,
-    NULL
-  );
+  sc = rtems_termios_device_install( &dev[0], &handler, NULL, NULL );
   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
 
-  sc = rtems_termios_device_remove( "/barfoo", major, minor );
-  rtems_test_assert( sc == RTEMS_UNSATISFIED );
-
-  sc = rtems_termios_device_open( major, minor, &args );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
-
-  sc = rtems_termios_device_remove( &dev[0], major, minor );
-  rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE );
-
-  sc = rtems_termios_device_close( &args );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
-
-  sc = rtems_termios_device_remove( &dev[0], major, minor );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+  rv = unlink( &dev[0] );
+  rtems_test_assert( rv == 0 );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 }
@@ -656,14 +614,12 @@ static void test_first_open_error(void)
   static const rtems_termios_device_handler handler = {
     .first_open = first_open_error
   };
-  static const rtems_device_major_number major = 123456789;
-  static const rtems_device_minor_number minor = 0xdeadbeef;
   static const char dev[] = "/foobar";
 
   rtems_resource_snapshot snapshot;
   rtems_status_code sc;
-  rtems_libio_t iop;
-  rtems_libio_open_close_args_t args;
+  int fd;
+  int rv;
   device_context ctx = {
     .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ),
     .done = false
@@ -671,27 +627,18 @@ static void test_first_open_error(void)
 
   rtems_resource_snapshot_take( &snapshot );
 
-  sc = rtems_termios_device_install(
-    &dev[0],
-    major,
-    minor,
-    &handler,
-    NULL,
-    &ctx.base
-  );
+  sc = rtems_termios_device_install( &dev[0], &handler, NULL, &ctx.base );
   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
 
-  memset( &iop, 0, sizeof( iop ) );
-  memset( &args, 0, sizeof( args ) );
-  args.iop = &iop;
-
   rtems_test_assert( !ctx.done );
-  sc = rtems_termios_device_open( major, minor, &args );
-  rtems_test_assert( sc == RTEMS_NO_MEMORY );
+  errno = 0;
+  fd = open( &dev[0], O_RDWR );
+  rtems_test_assert( fd == -1 );
+  rtems_test_assert( errno == ENOMEM );
   rtems_test_assert( ctx.done );
 
-  sc = rtems_termios_device_remove( &dev[0], major, minor );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+  rv = unlink( &dev[0] );
+  rtems_test_assert( rv == 0 );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 }
@@ -715,55 +662,38 @@ static void test_set_attributes_error(void)
   static const rtems_termios_device_handler handler = {
     .set_attributes = set_attributes_error
   };
-  static const rtems_device_major_number major = 123456789;
-  static const rtems_device_minor_number minor = 0xdeadbeef;
   static const char dev[] = "/foobar";
 
   rtems_resource_snapshot snapshot;
   rtems_status_code sc;
-  rtems_libio_t iop;
-  rtems_libio_open_close_args_t oc_args;
-  rtems_libio_ioctl_args_t io_args;
   struct termios term;
   device_context ctx = {
     .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ),
     .done = false
   };
+  int fd;
+  int rv;
 
   rtems_resource_snapshot_take( &snapshot );
 
-  sc = rtems_termios_device_install(
-    &dev[0],
-    major,
-    minor,
-    &handler,
-    NULL,
-    &ctx.base
-  );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
-
-  memset( &iop, 0, sizeof( iop ) );
-  memset( &oc_args, 0, sizeof( oc_args ) );
-  oc_args.iop = &iop;
-
-  sc = rtems_termios_device_open( major, minor, &oc_args );
+  sc = rtems_termios_device_install( &dev[0], &handler, NULL, &ctx.base );
   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
 
-  memset( &io_args, 0, sizeof( io_args ) );
-  io_args.iop = &iop;
-  io_args.command = RTEMS_IO_SET_ATTRIBUTES;
-  io_args.buffer = &term;
+  fd = open( &dev[0], O_RDWR );
+  rtems_test_assert( fd >= 0 );
 
   rtems_test_assert( !ctx.done );
-  sc = rtems_termios_ioctl( &io_args );
-  rtems_test_assert( sc == RTEMS_IO_ERROR );
+  errno = 0;
+  rv = ioctl( fd, RTEMS_IO_SET_ATTRIBUTES, &term );
+  rtems_test_assert( rv == -1 );
+  rtems_test_assert( errno == EIO );
   rtems_test_assert( ctx.done );
 
-  sc = rtems_termios_device_close( &oc_args );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+  rv = close( fd );
+  rtems_test_assert( rv == 0 );
 
-  sc = rtems_termios_device_remove( &dev[0], major, minor );
-  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+  rv = unlink( &dev[0] );
+  rtems_test_assert( rv == 0 );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 }
@@ -982,7 +912,7 @@ static rtems_task Init(
 /* configuration information */
 
 #define CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS \
-  { .initialization_entry = test_early_device_install_remove }
+  { .initialization_entry = test_early_device_install }
 
 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
diff --git a/testsuites/psxtests/psxfile01/test.c b/testsuites/psxtests/psxfile01/test.c
index abc9295..8fcb281 100644
--- a/testsuites/psxtests/psxfile01/test.c
+++ b/testsuites/psxtests/psxfile01/test.c
@@ -624,8 +624,9 @@ since new path is not valid");
   rtems_test_assert( ctime1 != ctime2);
 
   /* try to truncate the console and see what happens */
+  errno = 0;
   status = truncate( "/dev/console", 40 );
-  rtems_test_assert( status == 0 );
+  rtems_test_assert( status == 0 || ( status == -1 && errno == EINVAL ) );
 
   puts( "truncate /tmp/j to length of 0" );
   status = truncate( "/tmp/j", 0 );




More information about the vc mailing list