[PATCH 1/7] termios: Separate flow control from normal handler

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Oct 7 14:36:25 UTC 2014


---
 c/src/lib/libbsp/arm/tms570/console/tms570-sci.c |  5 +--
 c/src/lib/libbsp/sparc/leon3/console/console.c   |  2 +
 cpukit/libcsupport/include/rtems/termiostypes.h  | 35 ++++++++++++-----
 cpukit/libcsupport/src/termios.c                 | 23 +++++++----
 doc/bsp_howto/console.t                          |  1 +
 testsuites/libtests/termios01/init.c             | 49 ++++++++++++++++++++----
 6 files changed, 87 insertions(+), 28 deletions(-)

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 8aa3caf..961754e 100644
--- a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
+++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
@@ -103,6 +103,7 @@ rtems_device_driver console_initialize(
         major,
         minor,
         handler,
+	NULL,
         (void *) ctx
     );
     if ( sc != RTEMS_SUCCESSFUL ) {
@@ -536,8 +537,6 @@ const rtems_termios_device_handler tms570_sci_handler_polled = {
   .poll_read = tms570_sci_poll_read,
   .write = tms570_sci_poll_write,
   .set_attributes = tms570_sci_set_attributes,
-  .stop_remote_tx = NULL,
-  .start_remote_tx = NULL,
   .mode = TERMIOS_POLLED
 };
 
@@ -553,7 +552,5 @@ const rtems_termios_device_handler tms570_sci_handler_interrupt  = {
   .poll_read = NULL,
   .write = tms570_sci_interrupt_write,
   .set_attributes = tms570_sci_set_attributes,
-  .stop_remote_tx = NULL,
-  .start_remote_tx = NULL,
   .mode = TERMIOS_IRQ_DRIVEN
 };
diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c
index 9012492..513d45d 100644
--- a/c/src/lib/libbsp/sparc/leon3/console/console.c
+++ b/c/src/lib/libbsp/sparc/leon3/console/console.c
@@ -131,6 +131,7 @@ rtems_device_driver console_initialize(
       major,
       minor,
       handler,
+      NULL,
       leon3_console_get_uart(syscon_uart_index)
     );
     if (status != RTEMS_SUCCESSFUL)
@@ -147,6 +148,7 @@ rtems_device_driver console_initialize(
       major,
       minor,
       handler,
+      NULL,
       leon3_console_get_uart(syscon_uart_index)
     );
   }
diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
index 6339456..045a91f 100644
--- a/cpukit/libcsupport/include/rtems/termiostypes.h
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -144,6 +144,18 @@ typedef struct {
   );
 
   /**
+   * @brief Termios device mode.
+   */
+  rtems_termios_device_mode mode;
+} rtems_termios_device_handler;
+
+/**
+ * @brief Termios device flow control handler.
+ *
+ * @see rtems_termios_device_install().
+ */
+typedef struct {
+  /**
    * @brief Indicate to stop remote transmitter.
    *
    * @param[in] tty The Termios control.
@@ -160,12 +172,7 @@ typedef struct {
    * @see rtems_termios_get_device_context().
    */
   void (*start_remote_tx)(struct rtems_termios_tty *tty);
-
-  /**
-   * @brief Termios device mode.
-   */
-  rtems_termios_device_mode mode;
-} rtems_termios_device_handler;
+} rtems_termios_device_flow;
 
 /**
  * @brief Termios device node for installed devices.
@@ -177,6 +184,7 @@ typedef struct rtems_termios_device_node {
   rtems_device_major_number           major;
   rtems_device_minor_number           minor;
   const rtems_termios_device_handler *handler;
+  const rtems_termios_device_flow    *flow;
   void                               *context;
   struct rtems_termios_tty           *tty;
 } rtems_termios_device_node;
@@ -254,6 +262,11 @@ typedef struct rtems_termios_tty {
    */
   rtems_termios_device_handler handler;
 
+  /**
+   * @brief The device flow control handler.
+   */
+  rtems_termios_device_flow flow;
+
   volatile unsigned int    flow_ctrl;
   unsigned int             lowwater,highwater;
 
@@ -295,11 +308,14 @@ 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.
+ *   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.
  * @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
+ *   handler are optional and may be @c NULL.  If present must be persistent
+ *   throughout the installed time of the device.
  * @param[in] context The device context.  It must be persistent throughout the
  *   installed time of the device.
  *
@@ -307,17 +323,18 @@ typedef struct rtems_termios_tty {
  * @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.
+ *   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().
+ *   rtems_termios_device_close() and 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,
   void                               *context
 );
 
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index 52171a1..6119b22 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -133,6 +133,7 @@ rtems_status_code rtems_termios_device_install(
   rtems_device_major_number           major,
   rtems_device_minor_number           minor,
   const rtems_termios_device_handler *handler,
+  const rtems_termios_device_flow    *flow,
   void                               *context
 )
 {
@@ -148,6 +149,7 @@ rtems_status_code rtems_termios_device_install(
   new_device_node->major = major;
   new_device_node->minor = minor;
   new_device_node->handler = handler;
+  new_device_node->flow = flow;
   new_device_node->context = context;
   new_device_node->tty = NULL;
 
@@ -458,6 +460,11 @@ rtems_termios_open_tty(
     if (device_node != NULL) {
       device_node->tty = tty;
       tty->handler = *device_node->handler;
+
+      if (device_node->flow != NULL) {
+        tty->flow = *device_node->flow;
+      }
+
       tty->device_node = device_node;
       tty->device_context = device_node->context;
       memset(&tty->device, 0, sizeof(tty->device));
@@ -472,9 +479,9 @@ rtems_termios_open_tty(
         rtems_termios_callback_write : NULL;
       tty->handler.set_attributes = callbacks->setAttributes != NULL ?
         rtems_termios_callback_setAttributes : NULL;
-      tty->handler.stop_remote_tx = callbacks->stopRemoteTx != NULL ?
+      tty->flow.stop_remote_tx = callbacks->stopRemoteTx != NULL ?
         rtems_termios_callback_stopRemoteTx : NULL;
-      tty->handler.start_remote_tx = callbacks->startRemoteTx != NULL ?
+      tty->flow.start_remote_tx = callbacks->startRemoteTx != NULL ?
         rtems_termios_callback_startRemoteTx : NULL;
       tty->handler.mode = callbacks->outputUsesInterrupts;
       tty->device_context = NULL;
@@ -818,8 +825,8 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
 
     /* restart remote Tx, if it was stopped */
     if ((tty->flow_ctrl & FL_IRTSOFF) &&
-        (tty->handler.start_remote_tx != NULL)) {
-      tty->handler.start_remote_tx(tty);
+        (tty->flow.start_remote_tx != NULL)) {
+      tty->flow.start_remote_tx(tty);
     }
     tty->flow_ctrl &= ~(FL_IRTSOFF);
   }
@@ -1444,8 +1451,8 @@ fillBufferQueue (struct rtems_termios_tty *tty)
         } else if (tty->flow_ctrl & FL_MDRTS) {
           tty->flow_ctrl &= ~FL_IRTSOFF;
           /* activate RTS line */
-          if (tty->handler.start_remote_tx != NULL) {
-            tty->handler.start_remote_tx(tty);
+          if (tty->flow.start_remote_tx != NULL) {
+            tty->flow.start_remote_tx(tty);
           }
         }
       }
@@ -1624,8 +1631,8 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
         } else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF)) == (FL_MDRTS) ) {
           tty->flow_ctrl |= FL_IRTSOFF;
           /* deactivate RTS line */
-          if (tty->handler.stop_remote_tx != NULL) {
-            tty->handler.stop_remote_tx(tty);
+          if (tty->flow.stop_remote_tx != NULL) {
+            tty->flow.stop_remote_tx(tty);
           }
         }
       }
diff --git a/doc/bsp_howto/console.t b/doc/bsp_howto/console.t
index e35ca36..a165f72 100644
--- a/doc/bsp_howto/console.t
+++ b/doc/bsp_howto/console.t
@@ -489,6 +489,7 @@ rtems_device_driver console_initialize(
       major,
       minor,
       handler,
+      NULL,
       ctx
     );
     if (sc != RTEMS_SUCCESSFUL) @{
diff --git a/testsuites/libtests/termios01/init.c b/testsuites/libtests/termios01/init.c
index d1de3f8..080363f 100644
--- a/testsuites/libtests/termios01/init.c
+++ b/testsuites/libtests/termios01/init.c
@@ -560,17 +560,31 @@ static void test_device_install_remove(void)
 
   greedy = rtems_heap_greedy_allocate( NULL, 0 );
 
-  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL );
+  sc = rtems_termios_device_install( "/", major, minor, &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 );
+  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 );
+  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 );
@@ -578,7 +592,7 @@ static void test_device_install_remove(void)
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
 
-  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL );
+  sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL );
   rtems_test_assert( sc == RTEMS_UNSATISFIED );
 
   rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
@@ -586,7 +600,14 @@ static void test_device_install_remove(void)
   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 );
+  sc = rtems_termios_device_install(
+    &dev[0],
+    major,
+    minor,
+    &handler,
+    NULL,
+    NULL
+  );
   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
 
   sc = rtems_termios_device_remove( "/barfoo", major, minor );
@@ -638,7 +659,14 @@ static void test_first_open_error(void)
 
   rtems_resource_snapshot_take( &snapshot );
 
-  sc = rtems_termios_device_install( &dev[0], major, minor, &handler, &done );
+  sc = rtems_termios_device_install(
+    &dev[0],
+    major,
+    minor,
+    &handler,
+    NULL,
+    &done
+  );
   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
 
   memset( &iop, 0, sizeof( iop ) );
@@ -689,7 +717,14 @@ static void test_set_attributes_error(void)
 
   rtems_resource_snapshot_take( &snapshot );
 
-  sc = rtems_termios_device_install( &dev[0], major, minor, &handler, &done );
+  sc = rtems_termios_device_install(
+    &dev[0],
+    major,
+    minor,
+    &handler,
+    NULL,
+    &done
+  );
   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
 
   memset( &iop, 0, sizeof( iop ) );
-- 
1.8.4.5



More information about the devel mailing list