[PATCH 6/9] Adding USB serial driver test cases

Kevin Kirspel kevin-kirspel at idexx.com
Thu Feb 9 03:21:37 UTC 2017


---
 .../include/rtems/bsd/test/default-usb-init.h      | 158 +++++
 testsuite/usbserial/init.c                         | 373 ++++++++++++
 testsuite/usbserial01/test_main.c                  | 666 +++++++++++++++++++++
 testsuite/usbserial02/test_main.c                  | 252 ++++++++
 testsuite/usbserial03/test_main.c                  | 240 ++++++++
 testsuite/usbserial04/test_main.c                  | 226 +++++++
 testsuite/usbserial05/test_main.c                  | 303 ++++++++++
 testsuite/usbserial06/test_main.c                  | 218 +++++++
 8 files changed, 2436 insertions(+)
 create mode 100755 testsuite/include/rtems/bsd/test/default-usb-init.h
 create mode 100755 testsuite/usbserial/init.c
 create mode 100755 testsuite/usbserial01/test_main.c
 create mode 100755 testsuite/usbserial02/test_main.c
 create mode 100755 testsuite/usbserial03/test_main.c
 create mode 100755 testsuite/usbserial04/test_main.c
 create mode 100755 testsuite/usbserial05/test_main.c
 create mode 100755 testsuite/usbserial06/test_main.c

diff --git a/testsuite/include/rtems/bsd/test/default-usb-init.h b/testsuite/include/rtems/bsd/test/default-usb-init.h
new file mode 100755
index 0000000..051da86
--- /dev/null
+++ b/testsuite/include/rtems/bsd/test/default-usb-init.h
@@ -0,0 +1,158 @@
+/*
+ *  Shared Network Test Initialization File
+ */
+
+#ifndef RTEMS_BSD_TEST_DEFAULT_INIT_H
+#define RTEMS_BSD_TEST_DEFAULT_INIT_H
+
+#include <bsp.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <rtems/printer.h>
+#include <rtems/stackchk.h>
+#include <rtems/bsd/bsd.h>
+
+static void default_set_self_prio( rtems_task_priority prio )
+{
+  rtems_status_code sc;
+
+  sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
+  assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void default_on_exit( int exit_code, void *arg )
+{
+  rtems_printer printer;
+
+  rtems_print_printer_printf(&printer);
+  rtems_stack_checker_report_usage_with_plugin(&printer);
+
+  if ( exit_code == 0 ) {
+    puts( "*** END OF TEST " TEST_NAME " ***" );
+  }
+}
+
+rtems_task Init(
+  rtems_task_argument ignored
+)
+{
+  rtems_status_code sc;
+
+  /*
+   * Default the syslog priority to 'debug' to aid developers.
+   */
+  rtems_bsd_setlogpriority("debug");
+
+  puts( "*** " TEST_NAME " TEST ***" );
+
+  /*
+   *  BSD must support the new "shared IRQ PIC implementation" at this point.
+   *  BSPs must also provide rtems_interrupt_server_initialize() which
+   *  just requires including irq-server.[ch] in their build.
+   */
+
+  on_exit( default_on_exit, NULL );
+
+#ifdef DEFAULT_EARLY_INITIALIZATION
+  early_initialization();
+#endif
+
+  /* Let other tasks run to complete background work */
+  default_set_self_prio( RTEMS_MAXIMUM_PRIORITY - 2 );
+
+  rtems_bsd_initialize();
+
+  /* Let the callout timer allocate its resources */
+  sc = rtems_task_wake_after( 2 );
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  test_main();
+  /* should not return */
+
+  assert( 0 );
+}
+
+/*
+ * Configure RTEMS.
+ */
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
+#define CONFIGURE_MAXIMUM_DRIVERS 32
+
+#define CONFIGURE_FILESYSTEM_DOSFS
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+
+#define CONFIGURE_STACK_CHECKER_ENABLED
+
+#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024)
+#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (256 * 1024)
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/*
+ * Configure LIBBSD device.
+ */
+ #include <bsp/nexus-devices.h>
+
+/*
+ * Configure RTEMS Shell.
+ */
+#define CONFIGURE_SHELL_COMMANDS_INIT
+
+#include <bsp/irq-info.h>
+
+#include <rtems/netcmds-config.h>
+
+#define CONFIGURE_SHELL_USER_COMMANDS \
+  &bsp_interrupt_shell_command, \
+  &rtems_shell_STTY_Command, \
+  &rtems_shell_SYSCTL_Command
+
+#define CONFIGURE_SHELL_COMMAND_CPUUSE
+#define CONFIGURE_SHELL_COMMAND_PERIODUSE
+#define CONFIGURE_SHELL_COMMAND_STACKUSE
+#define CONFIGURE_SHELL_COMMAND_PROFREPORT
+
+#define CONFIGURE_SHELL_COMMAND_CP
+#define CONFIGURE_SHELL_COMMAND_PWD
+#define CONFIGURE_SHELL_COMMAND_LS
+#define CONFIGURE_SHELL_COMMAND_LN
+#define CONFIGURE_SHELL_COMMAND_LSOF
+#define CONFIGURE_SHELL_COMMAND_CHDIR
+#define CONFIGURE_SHELL_COMMAND_CD
+#define CONFIGURE_SHELL_COMMAND_MKDIR
+#define CONFIGURE_SHELL_COMMAND_RMDIR
+#define CONFIGURE_SHELL_COMMAND_CAT
+#define CONFIGURE_SHELL_COMMAND_MV
+#define CONFIGURE_SHELL_COMMAND_RM
+#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
+
+#define CONFIGURE_SHELL_COMMAND_BLKSTATS
+#define CONFIGURE_SHELL_COMMAND_BLKSYNC
+#define CONFIGURE_SHELL_COMMAND_MOUNT
+#define CONFIGURE_SHELL_COMMAND_UNMOUNT
+
+#include <rtems/shellconfig.h>
+
+#endif /* RTEMS_BSD_TEST_DEFAULT_INIT_H */
diff --git a/testsuite/usbserial/init.c b/testsuite/usbserial/init.c
new file mode 100755
index 0000000..2a65e6f
--- /dev/null
+++ b/testsuite/usbserial/init.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2010, 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/malloc.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL"
+
+#define USB_SERIAL_TEST_BUFFER_SIZE 48
+#define PRIO_OPEN  (RTEMS_MAXIMUM_PRIORITY - 12)
+#define PRIO_READ  (RTEMS_MAXIMUM_PRIORITY - 11)
+#define PRIO_WRITE (RTEMS_MAXIMUM_PRIORITY - 10)
+
+typedef struct
+{
+  int fd;
+  char rbuf[USB_SERIAL_TEST_BUFFER_SIZE];
+  char wbuf[USB_SERIAL_TEST_BUFFER_SIZE];
+}usb_test_message_t;
+
+static rtems_id oid, rid, wid, omid, rmid, wmid;
+static volatile bool kill_otask, kill_rtask, kill_wtask;
+static volatile bool otask_active, rtask_active, wtask_active;
+
+static void
+usb_serial_read_task(rtems_task_argument arg)
+{
+  usb_test_message_t msg;
+  uint32_t size, end_time;
+  int bytes, index;
+
+  rtask_active = true;
+  kill_rtask = false;
+  while(!kill_rtask)
+  {
+    rtems_message_queue_receive( rmid, &msg, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+    index = 0;
+    msg.rbuf[0] = 0;
+    end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(500);
+    while(( rtems_clock_get_ticks_since_boot() < end_time ) && ( index < sizeof(msg.rbuf)))
+    {
+      bytes = read(msg.fd, &msg.rbuf[index], sizeof(msg.rbuf) - index - 1);
+      if( bytes < 0)
+      {
+        msg.fd = -1;
+        rtems_message_queue_send( omid, &msg, sizeof( msg ));
+        printf( "serial device read error: %d\n", errno );
+      }
+      else if( bytes > 0)
+      {
+        index += bytes;
+        msg.rbuf[index] = 0;
+        if( strcmp( msg.rbuf, msg.wbuf ) == 0 )
+        {
+          break;
+        }
+      }
+      rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(10));
+    }
+    printf( "serial device read: %s - %s\n", msg.rbuf, strcmp( msg.rbuf, msg.wbuf ) == 0 ? "PASS" : "FAIL" );
+  }
+  rtask_active = false;
+}
+
+static void
+usb_serial_write_task(rtems_task_argument arg)
+{
+  usb_test_message_t msg;
+  uint32_t size;
+  int bytes, write_len, count = 0;
+
+  wtask_active = true;
+  kill_wtask = false;
+  while(!kill_wtask)
+  {
+    rtems_message_queue_receive( wmid, &msg, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+    count++;
+    sprintf( msg.wbuf, "Hello World %d", count );
+    write_len = strlen( msg.wbuf );
+    bytes = write(msg.fd, msg.wbuf, write_len);
+    if( bytes < 0)
+    {
+      msg.fd = -1;
+      rtems_message_queue_send( omid, &msg, sizeof( msg ));
+      printf( "serial device write error: %d\n", errno );
+    }
+    else if( bytes != write_len)
+    {
+      printf( "serial device failed to write all bytes: %d\n", bytes );
+    }
+    else
+    {
+      printf( "serial device write: %s\n", msg.wbuf );
+      rtems_message_queue_send( rmid, &msg, sizeof( msg ));
+    }
+  }
+  wtask_active = false;
+}
+
+static void
+usb_serial_open_task(rtems_task_argument arg)
+{
+  rtems_status_code sc;
+  usb_test_message_t msg;
+  struct termios t;
+  uint32_t size;
+  int fd, iret;
+
+  fd = -2;
+  otask_active = true;
+  kill_otask = false;
+  while(!kill_otask)
+  {
+    sc = rtems_message_queue_receive( omid, &msg, &size, RTEMS_WAIT, RTEMS_MILLISECONDS_TO_TICKS(1000));
+    if(sc == RTEMS_SUCCESSFUL)
+    {
+      if(fd >= 0)
+      {
+        close(fd);
+        printf( "serial device closed\n" );
+      }
+      fd = msg.fd;
+    }
+    if(fd == -1)
+    {
+      fd = open( "/dev/ttyU0", LIBIO_FLAGS_READ_WRITE );
+      if( fd != -1 )
+      {
+        printf( "serial device opened\n" );
+        //get terminal settings
+        iret = tcgetattr ( fd, &t );
+        assert( iret != -1 );
+        //set timeouts to zero for non-blocking mode
+        t.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+        //t.c_iflag &= ~(BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP);
+        //t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP);
+        t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+        t.c_iflag |= IXON;    // Enable XON/XOFF flow control on output.
+        t.c_cflag &= ~(CSIZE | PARENB);
+        t.c_oflag &= ~(OPOST);
+        t.c_cflag |= ( CS8 | CREAD );
+        t.c_cc[VMIN] = 0;
+        t.c_cc[VTIME] = 0;
+        //save settings
+        iret = tcsetattr ( fd, TCSANOW, &t );
+        assert( iret != -1 );
+        msg.fd = fd;
+        rtems_message_queue_send( wmid, &msg, sizeof( msg ));
+      }
+    }
+    else
+    {
+      msg.fd = fd;
+      rtems_message_queue_send( wmid, &msg, sizeof( msg ));
+    }
+  }
+  otask_active = false;
+}
+
+static void
+Init(rtems_task_argument arg)
+{
+  rtems_status_code sc;
+  usb_test_message_t msg;
+  int ii;
+
+  (void) arg;
+  puts( "*** " TEST_NAME " TEST ***" );
+
+  sc = rtems_message_queue_create(
+    rtems_build_name ( 'M', 'U', 'O', 'P' ),
+    16,
+    sizeof(usb_test_message_t),
+    RTEMS_PRIORITY,
+    &omid
+  );
+  assert( sc == RTEMS_SUCCESSFUL );
+
+  sc = rtems_message_queue_create(
+    rtems_build_name ( 'M', 'U', 'R', 'D' ),
+    16,
+    sizeof(usb_test_message_t),
+    RTEMS_PRIORITY,
+    &rmid
+  );
+  assert( sc == RTEMS_SUCCESSFUL );
+
+  sc = rtems_message_queue_create(
+    rtems_build_name ( 'M', 'U', 'W', 'R' ),
+    16,
+    sizeof(usb_test_message_t),
+    RTEMS_PRIORITY,
+    &wmid
+  );
+  assert( sc == RTEMS_SUCCESSFUL );
+
+  sc = rtems_task_create(
+    rtems_build_name('U', 'S', 'B', 'R'),
+    PRIO_READ,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_FLOATING_POINT,
+    &rid
+  );
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_create(
+    rtems_build_name('U', 'S', 'B', 'W'),
+    PRIO_WRITE,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_FLOATING_POINT,
+    &wid
+  );
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_create(
+    rtems_build_name('U', 'S', 'B', 'O'),
+    PRIO_OPEN,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_FLOATING_POINT,
+    &oid
+  );
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(rid, usb_serial_read_task, NULL);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(oid, usb_serial_open_task, NULL);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(wid, usb_serial_write_task, NULL);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_bsd_initialize();
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  msg.fd = -1;
+  rtems_message_queue_send( omid, &msg, sizeof( msg ));
+
+  sc = rtems_shell_init("SHLL", 16 * 1024, 1, CONSOLE_DEVICE_NAME,
+      false, true, NULL);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  kill_otask = true;
+  kill_rtask = true;
+  kill_wtask = true;
+  while(otask_active || rtask_active || wtask_active)
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(10));
+  }
+
+  sc = rtems_message_queue_delete(wmid);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_message_queue_delete(rmid);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_message_queue_delete(omid);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  exit(0);
+}
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
+#define CONFIGURE_MAXIMUM_DRIVERS 32
+
+#define CONFIGURE_FILESYSTEM_DOSFS
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+
+#define CONFIGURE_STACK_CHECKER_ENABLED
+
+#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024)
+#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (256 * 1024)
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+#include <bsp/nexus-devices.h>
+
+#define CONFIGURE_SHELL_COMMANDS_INIT
+
+#include <bsp/irq-info.h>
+
+#include <rtems/netcmds-config.h>
+
+#define CONFIGURE_SHELL_USER_COMMANDS \
+  &bsp_interrupt_shell_command, \
+  &rtems_shell_STTY_Command, \
+  &rtems_shell_SYSCTL_Command
+
+#define CONFIGURE_SHELL_COMMAND_CPUUSE
+#define CONFIGURE_SHELL_COMMAND_PERIODUSE
+#define CONFIGURE_SHELL_COMMAND_STACKUSE
+#define CONFIGURE_SHELL_COMMAND_PROFREPORT
+
+#define CONFIGURE_SHELL_COMMAND_CP
+#define CONFIGURE_SHELL_COMMAND_PWD
+#define CONFIGURE_SHELL_COMMAND_LS
+#define CONFIGURE_SHELL_COMMAND_LN
+#define CONFIGURE_SHELL_COMMAND_LSOF
+#define CONFIGURE_SHELL_COMMAND_CHDIR
+#define CONFIGURE_SHELL_COMMAND_CD
+#define CONFIGURE_SHELL_COMMAND_MKDIR
+#define CONFIGURE_SHELL_COMMAND_RMDIR
+#define CONFIGURE_SHELL_COMMAND_CAT
+#define CONFIGURE_SHELL_COMMAND_MV
+#define CONFIGURE_SHELL_COMMAND_RM
+#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
+
+#define CONFIGURE_SHELL_COMMAND_BLKSTATS
+#define CONFIGURE_SHELL_COMMAND_BLKSYNC
+#define CONFIGURE_SHELL_COMMAND_MOUNT
+#define CONFIGURE_SHELL_COMMAND_UNMOUNT
+
+#include <rtems/shellconfig.h>
diff --git a/testsuite/usbserial01/test_main.c b/testsuite/usbserial01/test_main.c
new file mode 100755
index 0000000..63fcc83
--- /dev/null
+++ b/testsuite/usbserial01/test_main.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 1"
+
+/* rtems_termios_baud_t is a typedefs to int32_t */
+#define PRIdrtems_termios_baud_t PRId32
+
+/**
+ *  This macro defines the standard name for the USB serial device
+ *  that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+/*
+ *  Baud Rate Constant Mapping Entry
+ */
+typedef struct {
+  tcflag_t constant;
+  rtems_termios_baud_t baud;
+} termios_baud_test_r;
+
+#define INVALID_CONSTANT ((tcflag_t) -2)
+
+#define INVALID_BAUD ((rtems_termios_baud_t) -2)
+/*
+ *  Baud Rate Constant Mapping Table
+ */
+static const termios_baud_test_r baud_table[] = {
+  { B0,           0 },
+  { B50,         50 },
+  { B75,         75 },
+  { B110,       110 },
+  { B134,       134 },
+  { B150,       150 },
+  { B200,       200 },
+  { B300,       300 },
+  { B600,       600 },
+  { B1200,     1200 },
+  { B1800,     1800 },
+  { B2400,     2400 },
+  { B4800,     4800 },
+  { B9600,     9600 },
+  { B19200,   19200 },
+  { B38400,   38400 },
+  { B57600,   57600 },
+  { B115200, 115200 },
+  { B230400, 230400 },
+  { B460800, 460800 },
+  { INVALID_CONSTANT, INVALID_BAUD }
+};
+
+/*
+ *  Character Size Constant Mapping Entry
+ */
+typedef struct {
+  tcflag_t constant;
+  int bits;
+} termios_character_size_test_r;
+
+/*
+ *  Character Size Constant Mapping Table
+ */
+static const termios_character_size_test_r char_size_table[] = {
+  { CS5,      5 },
+  { CS6,      6 },
+  { CS7,      7 },
+  { CS8,      8 },
+  { INVALID_CONSTANT, -1 }
+};
+
+/*
+ *  Parity Constant Mapping Entry
+ */
+typedef struct {
+  tcflag_t constant;
+  const char *parity;
+} termios_parity_test_r;
+
+/*
+ *  Parity Constant Mapping Table
+ */
+static const termios_parity_test_r parity_table[] = {
+  { 0,                "none" },
+  { PARENB,           "even" },
+  { PARENB | PARODD,  "odd" },
+  { INVALID_CONSTANT, NULL }
+};
+
+/*
+ *  Stop Bit Constant Mapping Entry
+ */
+typedef struct {
+  tcflag_t constant;
+  int stop;
+} termios_stop_bits_test_r;
+
+/*
+ *  Stop Bit Constant Mapping Table
+ */
+static const termios_stop_bits_test_r stop_bits_table[] = {
+  { 0,       1 },
+  { CSTOPB,  2 },
+  { INVALID_CONSTANT, -1 }
+};
+
+/*
+ *  Test converting baud rate into an index
+ */
+static void test_termios_baud2index(void)
+{
+  int i;
+  int index;
+
+  puts( "Test termios_baud2index..." );
+  puts( "termios_baud_to_index(-2) - NOT OK" );
+  i = rtems_termios_baud_to_index( INVALID_CONSTANT );
+  assert( i == -1 );
+
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    printf(
+      "termios_baud_to_index(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    index = rtems_termios_baud_to_index( baud_table[i].constant );
+    assert(index == i);
+  }
+}
+
+/*
+ *  Test converting termios baud constant to baud number
+ */
+static void test_termios_baud2number(void)
+{
+  int i;
+  rtems_termios_baud_t number;
+
+  puts(
+    "\n"
+    "Test termios_baud2number..."
+  );
+  puts( "termios_baud_to_number(-2) - NOT OK" );
+  number = rtems_termios_baud_to_number( INVALID_CONSTANT );
+  assert( number == 0 );
+
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    printf(
+      "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    number = rtems_termios_baud_to_number( baud_table[i].constant );
+    assert( number == baud_table[i].baud );
+  }
+}
+
+/*
+ *  Test converting baud number to termios baud constant
+ */
+static void test_termios_number_to_baud(void)
+{
+  int i;
+  tcflag_t termios_baud;
+
+  puts(
+    "\n"
+    "Test termios_number_to_baud..."
+  );
+  puts( "termios_number_to_baud(-2) - NOT OK" );
+  termios_baud = rtems_termios_number_to_baud( INVALID_BAUD );
+  assert( termios_baud == 0 );
+
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    printf(
+      "termios_number_to_baud(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    termios_baud = rtems_termios_number_to_baud( baud_table[i].baud );
+    assert( termios_baud == baud_table[i].constant );
+  }
+}
+
+/*
+ *  Test all the baud rate options
+ */
+static void test_termios_set_baud(
+  int test
+)
+{
+  int             sc;
+  int             i;
+  struct termios  attr;
+
+  puts( "Test termios setting device baud rate..." );
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    tcflag_t cbaud = CBAUD;
+
+    sc = tcgetattr( test, &attr );
+    assert(sc == 0);
+
+    attr.c_cflag &= ~cbaud;
+    attr.c_cflag |= baud_table[i].constant;
+
+    printf(
+      "tcsetattr(TCSANOW, B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+
+    printf(
+      "tcsetattr(TCSADRAIN, B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+  }
+}
+
+/*
+ *  Test all the character size options
+ */
+static void test_termios_set_charsize(
+  int test
+)
+{
+  int             sc;
+  int             i;
+  struct termios  attr;
+
+  puts(
+    "\n"
+    "Test termios setting device character size ..."
+  );
+  for (i=0 ; char_size_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    tcflag_t csize = CSIZE;
+
+    sc = tcgetattr( test, &attr );
+    assert(sc == 0);
+
+    attr.c_cflag &= ~csize;
+    attr.c_cflag |= char_size_table[i].constant;
+
+    printf( "tcsetattr(TCSANOW, CS%d) - OK\n", char_size_table[i].bits );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+
+    printf( "tcsetattr(TCSADRAIN, CS%d) - OK\n", char_size_table[i].bits );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+  }
+}
+
+/*
+ *  Test all the parity options
+ */
+static void test_termios_set_parity(
+  int test
+)
+{
+  int             sc;
+  int             i;
+  struct termios  attr;
+  tcflag_t        par;
+
+  puts(
+    "\n"
+    "Test termios setting device parity ..."
+  );
+  for (i=0 ; parity_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    par = PARENB | PARODD;
+
+    sc = tcgetattr( test, &attr );
+    assert(sc == 0);
+
+    attr.c_cflag &= ~par;
+    attr.c_cflag |= parity_table[i].constant;
+
+    printf( "tcsetattr(TCSANOW, %s) - OK\n", parity_table[i].parity );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+
+    printf( "tcsetattr(TCSADRAIN, %s) - OK\n", parity_table[i].parity );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+  }
+}
+
+/*
+ *  Test all the stop bit options
+ */
+static void test_termios_set_stop_bits(
+  int test
+)
+{
+  int             sc;
+  int             i;
+  struct termios  attr;
+
+  puts(
+    "\n"
+    "Test termios setting device character size ..."
+  );
+  for (i=0 ; stop_bits_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    tcflag_t cstopb = CSTOPB;
+
+    sc = tcgetattr( test, &attr );
+    assert(sc == 0);
+
+    attr.c_cflag &= ~cstopb;
+    attr.c_cflag |= stop_bits_table[i].constant;
+
+    printf( "tcsetattr(TCSANOW, %d bit%s) - OK\n",
+      stop_bits_table[i].stop,
+      ((stop_bits_table[i].stop == 1) ? "" : "s")
+    );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+
+    printf( "tcsetattr(TCSADRAIN, %d bits) - OK\n", stop_bits_table[i].stop );
+    sc = tcsetattr( test, TCSANOW, &attr );
+    assert(sc == 0);
+  }
+}
+
+static void test_termios_cfoutspeed(void)
+{
+  int i;
+  int sc;
+  speed_t speed;
+  struct termios term;
+  tcflag_t        bad;
+
+  bad = CBAUD << 1;
+  memset( &term, '\0', sizeof(term) );
+  puts( "cfsetospeed(BAD BAUD) - EINVAL" );
+  sc = cfsetospeed( &term, bad );
+  assert( sc == -1 );
+  assert( errno == EINVAL );
+
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    memset( &term, '\0', sizeof(term) );
+    printf(
+      "cfsetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    sc = cfsetospeed( &term, baud_table[i].constant );
+    assert( !sc );
+    printf(
+      "cfgetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    speed = cfgetospeed( &term );
+    assert( speed == baud_table[i].constant );
+  }
+}
+
+static void test_termios_cfinspeed(void)
+{
+  int             i;
+  int             sc;
+  speed_t         speed;
+  struct termios  term;
+  tcflag_t        bad;
+
+  bad = CBAUD << 1;
+  memset( &term, '\0', sizeof(term) );
+  puts( "cfsetispeed(BAD BAUD) - EINVAL" );
+  sc = cfsetispeed( &term, bad );
+  assert( sc == -1 );
+  assert( errno == EINVAL );
+
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    memset( &term, '\0', sizeof(term) );
+    printf(
+      "cfsetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    sc = cfsetispeed( &term, baud_table[i].constant );
+    assert( !sc );
+
+    printf(
+      "cfgetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    speed = cfgetispeed( &term );
+    assert( speed == baud_table[i].constant );
+  }
+}
+
+static void test_termios_cfsetspeed(void)
+{
+  int             i;
+  int             status;
+  speed_t         speed;
+  struct termios  term;
+  tcflag_t        bad;
+
+  bad = CBAUD << 1;
+  memset( &term, '\0', sizeof(term) );
+  puts( "cfsetspeed(BAD BAUD) - EINVAL" );
+  status = cfsetspeed( &term, bad );
+  assert( status == -1 );
+  assert( errno == EINVAL );
+
+  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+    memset( &term, '\0', sizeof(term) );
+    printf(
+      "cfsetspeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+      baud_table[i].baud
+    );
+    status = cfsetspeed( &term, baud_table[i].constant );
+    assert( !status );
+
+    printf(
+      "cfgetspeed(B%" PRIdrtems_termios_baud_t ") - checking both inspeed and outspeed - OK\n",
+      baud_table[i].baud
+    );
+    speed = cfgetispeed( &term );
+    assert( speed == baud_table[i].constant );
+
+    speed = cfgetospeed( &term );
+    assert( speed == baud_table[i].constant );
+  }
+}
+
+static void test_termios_cfmakeraw(void)
+{
+  struct termios  term;
+
+  memset( &term, '\0', sizeof(term) );
+  cfmakeraw( &term );
+  puts( "cfmakeraw - OK" );
+
+  /* Check that all of the flags were set correctly */
+  assert( ~(term.c_iflag & (IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON)) );
+
+  assert( ~(term.c_oflag & OPOST) );
+
+  assert( ~(term.c_lflag & (ECHO|ECHONL|ICANON|ISIG|IEXTEN)) );
+
+  assert( ~(term.c_cflag & (CSIZE|PARENB)) );
+
+  assert( term.c_cflag & CS8 );
+}
+
+static void test_set_best_baud(void)
+{
+  static const struct {
+    uint32_t baud;
+    tcflag_t cflag;
+  } baud_to_cflag_table[] = {
+    { 0,          B0 },
+    { 25,         B0 },
+    { 26,         B50 },
+    { 50,         B50 },
+    { 62,         B50 },
+    { 63,         B75 },
+    { 75,         B75 },
+    { 110,        B110 },
+    { 134,        B134 },
+    { 150,        B150 },
+    { 200,        B200 },
+    { 300,        B300 },
+    { 600,        B600 },
+    { 1200,       B1200 },
+    { 1800,       B1800 },
+    { 2400,       B2400 },
+    { 4800,       B4800 },
+    { 9600,       B9600 },
+    { 19200,      B19200 },
+    { 38400,      B38400 },
+    { 57600,      B57600 },
+    { 115200,     B115200 },
+    { 230400,     B230400 },
+    { 460800,     B460800 },
+    { 0xffffffff, B460800 }
+  };
+
+  size_t n = RTEMS_ARRAY_SIZE(baud_to_cflag_table);
+  size_t i;
+
+  for ( i = 0; i < n; ++i ) {
+    struct termios term;
+    tcflag_t cbaud_mask = CBAUD;
+
+    memset( &term, 0xff, sizeof( term ) );
+    rtems_termios_set_best_baud( &term, baud_to_cflag_table[ i ].baud );
+
+    assert(
+      (term.c_cflag & cbaud_mask) == baud_to_cflag_table[ i ].cflag
+    );
+  }
+}
+
+static void
+test_main(void)
+{
+  int                       rc;
+  rtems_status_code         sc;
+  rtems_device_major_number registered;
+  int                       test;
+  struct termios            t;
+  int index = 0;
+  int end_time;
+
+  /*
+   * Test baud rate
+   */
+  test_termios_baud2index();
+  test_termios_baud2number();
+  test_termios_number_to_baud();
+
+  puts( "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+  test = -1;
+  end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+  while((test == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+    test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    if(test == -1) {
+      puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+    }
+  }
+  assert(test != -1);
+  /*
+   * tcsetattr - ERROR invalid operation
+   */
+  puts( "tcsetattr - invalid operation - ENOTSUP" );
+  rc = tcsetattr( test, INT_MAX, &t );
+  assert(rc == -1);
+  assert(errno == ENOTSUP);
+
+  test_termios_cfmakeraw();
+
+  /*
+   * tcsetattr - TCSADRAIN
+   */
+  puts( "\ntcsetattr - drain - OK" );
+  rc = tcsetattr( test,  TCSADRAIN, &t );
+  assert(rc == 0);
+
+  test_termios_set_baud(test);
+
+  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+  rc = close( test );
+  assert(rc == 0);
+
+  /*
+   * Test character size
+   */
+  puts(
+    "\n"
+    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
+  );
+  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+  assert(test != -1);
+
+  test_termios_set_charsize(test);
+
+  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+  rc = close( test );
+  assert(rc == 0);
+
+  /*
+   * Test parity
+   */
+  puts(
+    "\n"
+    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
+  );
+  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+  assert(test != -1);
+
+  test_termios_set_parity(test);
+
+  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+  rc = close( test );
+  assert(rc == 0);
+
+  /*
+   * Test stop bits
+   */
+  puts(
+    "\n"
+    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
+  );
+  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+  assert(test != -1);
+
+  test_termios_set_stop_bits(test);
+
+  test_termios_cfoutspeed();
+
+  test_termios_cfinspeed();
+
+  test_termios_cfsetspeed();
+
+  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+  rc = close( test );
+  assert(rc == 0);
+
+  puts( "Multiple open of the device" );
+  for( ; index < 26; ++index ) {
+    test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    assert(test != -1);
+    rc = close( test );
+    assert(rc == 0);
+  }
+  puts( "" );
+
+  test_set_best_baud();
+
+	exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial02/test_main.c b/testsuite/usbserial02/test_main.c
new file mode 100755
index 0000000..036b57b
--- /dev/null
+++ b/testsuite/usbserial02/test_main.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 2"
+
+/**
+ *  This macro defines the standard name for the USB serial device
+ *  that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+
+int Test_fd;
+
+void open_it(void)
+{
+  int end_time;
+
+  puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  Test_fd = -1;
+  end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+  while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+    Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    if(Test_fd == -1) {
+      puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+    }
+  }
+  assert( Test_fd != -1 );
+
+	change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+	change_lflag("", ECHO|ECHONL|ISIG|IEXTEN, 0);
+	change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+  int rc;
+
+  puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  rc = close( Test_fd );
+  assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_iflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_iflag &= ~mask;
+  attr.c_iflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_lflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_lflag &= ~mask;
+  attr.c_lflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_oflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_oflag &= ~mask;
+  attr.c_oflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+static void
+test_main(void)
+{
+  int sc;
+  pid_t pid;
+  char *term_name_p;
+  char term_name[32];
+
+  open_it();
+
+  puts( "tcdrain() - OK" );
+  sc = tcdrain(Test_fd);
+  assert( !sc );
+
+  puts( "" );
+
+  /***** TEST TCFLOW *****/
+  puts( "tcflow(TCOOFF) - ENOTSUP" );
+  errno = 0;
+  sc = tcflow( Test_fd, TCOOFF );
+  assert( sc == -1 );
+  assert( errno == ENOTSUP );
+
+  puts( "tcflow(TCOON) - ENOTSUP" );
+  errno = 0;
+  sc = tcflow( Test_fd, TCOON );
+  assert( sc == -1 );
+  assert( errno == ENOTSUP );
+
+  puts( "tcflow(TCIOFF) - ENOTSUP" );
+  errno = 0;
+  sc = tcflow( Test_fd, TCIOFF );
+  assert( sc == -1 );
+  assert( errno == ENOTSUP );
+
+  puts( "tcflow(TCION) - ENOTSUP" );
+  errno = 0;
+  sc = tcflow( Test_fd, TCION );
+  assert( sc == -1 );
+  assert( errno == ENOTSUP );
+
+  puts( "tcflow(22) - EINVAL" );
+  errno = 0;
+  sc = tcflow( Test_fd, 22 );
+  assert( sc == -1 );
+  assert( errno == EINVAL );
+
+  puts( "" );
+
+  /***** TEST TCFLUSH *****/
+  puts( "tcflush(TCIFLUSH) - OK" );
+  errno = 0;
+  sc = tcflush( Test_fd, TCIFLUSH );
+  assert( sc == 0 );
+  assert( errno == 0 );
+
+  puts( "tcflush(TCOFLUSH) - OK" );
+  sc = tcflush( Test_fd, TCOFLUSH );
+  assert( sc == 0 );
+  assert( errno == 0 );
+
+  puts( "tcflush(TCIOFLUSH) - OK" );
+  sc = tcflush( Test_fd, TCIOFLUSH );
+  assert( sc == 0 );
+  assert( errno == 0 );
+
+  puts( "tcflush(22) - EINVAL" );
+  errno = 0;
+  sc = tcflush( Test_fd, 22 );
+  assert( sc == -1 );
+  assert( errno == EINVAL );
+
+  puts( "" );
+
+  /***** TEST TCGETPGRP *****/
+  puts( "tcgetpgrp() - OK" );
+  pid = tcgetpgrp(Test_fd);
+  assert( pid == getpid() );
+
+  puts( "tcsetpgrp(3) - OK" );
+  sc = tcsetpgrp( Test_fd, 3 );
+  assert( !sc );
+
+  puts( "" );
+
+  /***** TEST TCSENDBREAK *****/
+  puts( "tcsendbreak(0) - OK" );
+  sc = tcsendbreak( Test_fd, 0 );
+  assert( !sc );
+
+  puts( "" );
+
+  /***** TEST CTERMID *****/
+  puts( "ctermid( NULL ) - OK" );
+  term_name_p = ctermid( NULL );
+  assert( term_name_p );
+  printf( "ctermid ==> %s\n", term_name_p );
+
+  puts( "ctermid( term_name ) - OK" );
+  term_name_p = ctermid( term_name );
+  assert( term_name_p == term_name );
+  printf( "ctermid ==> %s\n", term_name_p );
+
+  close_it();
+
+	exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial03/test_main.c b/testsuite/usbserial03/test_main.c
new file mode 100755
index 0000000..e914ce0
--- /dev/null
+++ b/testsuite/usbserial03/test_main.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 3"
+
+/**
+ *  This macro defines the standard name for the USB serial device
+ *  that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void write_helper(int fd, const char *c);
+void read_helper(int fd, const char *expected);
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+
+void write_helper(
+  int        fd,
+  const char *c
+)
+{
+  size_t   len;
+  int      rc;
+
+  len = strlen( c );
+  printf( "Writing: %s", c );
+
+  rc = write( fd, c, len );
+  assert( rc == len );
+}
+
+uint8_t read_helper_buffer[256];
+
+void read_helper(
+  int         fd,
+  const char *expected
+)
+{
+  int    rc;
+  size_t len;
+
+  len = strlen( expected );
+
+  printf( "\nReading (expected):\n" );
+  rtems_print_buffer( (unsigned char *)expected, len-1 );
+
+  rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) );
+  assert( rc != -1 );
+
+  printf( "Read %d bytes from read(2)\n", rc );
+  rtems_print_buffer( read_helper_buffer, rc );
+}
+
+int Test_fd;
+
+void open_it(void)
+{
+  int end_time;
+
+  puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  Test_fd = -1;
+  end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+  while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+    Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    if(Test_fd == -1) {
+      puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+    }
+  }
+  assert( Test_fd != -1 );
+
+	change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+	change_lflag("", ECHO|ECHONL|ISIG|IEXTEN, 0);
+	change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+  int rc;
+
+  puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  rc = close( Test_fd );
+  assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_iflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_iflag &= ~mask;
+  attr.c_iflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_lflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_lflag &= ~mask;
+  attr.c_lflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_oflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_oflag &= ~mask;
+  attr.c_oflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+const char ExpectedOutput_1[] = "This is test output.\n";
+const char ExpectedInput_1[] = "Test input this is.\n";
+const char ExpectedInput_2[] = "1235\b456.\n";
+const char ExpectedInput_3[] = "tab\ttab.\n";
+const char ExpectedInput_4[] = "cr\r.\n";
+const char ExpectedInput_5[] = "aBcDeFgH.\n";
+const char ExpectedInput_6[] = "Testing VERASE\177.\n";
+const char ExpectedInput_7[] = "Testing VKILL\025.\n";
+const char ExpectedInput_8[] = "\177Testing VERASE in column 1.\n";
+const char ExpectedInput_9[] = "\t tab \tTesting VKILL after tab.\025\n";
+
+static void
+test_main(void)
+{
+  open_it();
+
+  /* some basic cases */
+  write_helper( Test_fd, ExpectedOutput_1 );
+  read_helper( Test_fd, ExpectedOutput_1 );
+  write_helper( Test_fd, ExpectedInput_1 );
+  read_helper( Test_fd, ExpectedInput_1 );
+  write_helper( Test_fd, ExpectedInput_2 );
+  read_helper( Test_fd, ExpectedInput_2 );
+  write_helper( Test_fd, ExpectedInput_3 );
+  read_helper( Test_fd, ExpectedInput_3 );
+  write_helper( Test_fd, ExpectedInput_4 );
+  read_helper( Test_fd, ExpectedInput_4 );
+
+  /* test to lower case input mapping */
+  write_helper( Test_fd, ExpectedInput_5 );
+  read_helper( Test_fd, ExpectedInput_5 );
+	//IUCLC is not supported within FREEBSD so this should not change the output
+  change_iflag( "Enable to lower case mapping on input", IUCLC, IUCLC );
+  write_helper( Test_fd, ExpectedInput_5 );
+  read_helper( Test_fd, ExpectedInput_5 );
+  change_iflag( "Disable to lower case mapping on input", IUCLC, 0 );
+
+  write_helper( Test_fd, ExpectedInput_6 );
+  read_helper( Test_fd, ExpectedInput_6 );
+  write_helper( Test_fd, ExpectedInput_7 );
+  read_helper( Test_fd, ExpectedInput_7 );
+  write_helper( Test_fd, ExpectedInput_8 );
+  read_helper( Test_fd, ExpectedInput_8 );
+  write_helper( Test_fd, ExpectedInput_9 );
+  read_helper( Test_fd, ExpectedInput_9 );
+
+  puts( "" );
+  close_it();
+
+	exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial04/test_main.c b/testsuite/usbserial04/test_main.c
new file mode 100755
index 0000000..1f40159
--- /dev/null
+++ b/testsuite/usbserial04/test_main.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 4"
+
+/**
+ *  This macro defines the standard name for the USB serial device
+ *  that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void write_helper(int fd, const char *c);
+void read_helper(int fd, const char *expected);
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+
+void write_helper(
+  int        fd,
+  const char *c
+)
+{
+  size_t   len;
+  int      rc;
+
+  len = strlen( c );
+  printf( "Writing: %s", c );
+
+  rc = write( fd, c, len );
+  assert( rc == len );
+}
+
+uint8_t read_helper_buffer[256];
+
+void read_helper(
+  int         fd,
+  const char *expected
+)
+{
+  int    rc;
+  size_t len;
+
+  len = strlen( expected );
+
+  printf( "\nReading (expected):\n" );
+  rtems_print_buffer( (unsigned char *)expected, len-1 );
+
+  rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) );
+  assert( rc != -1 );
+
+  printf( "Read %d bytes from read(2)\n", rc );
+  rtems_print_buffer( read_helper_buffer, rc );
+}
+
+int Test_fd;
+
+void open_it(void)
+{
+  int end_time;
+
+  puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  Test_fd = -1;
+  end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+  while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+    Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    if(Test_fd == -1) {
+      puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+    }
+  }
+  assert( Test_fd != -1 );
+
+	change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+	change_lflag("", ECHO|ECHONL|ISIG|IEXTEN, 0);
+	change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+  int rc;
+
+  puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  rc = close( Test_fd );
+  assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_iflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_iflag &= ~mask;
+  attr.c_iflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_lflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_lflag &= ~mask;
+  attr.c_lflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_oflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_oflag &= ~mask;
+  attr.c_oflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+const char ExpectedOutput_1[] = "This is test output.\n";
+const char ExpectedInput_1[] = "Test input this is.\n";
+const char ExpectedInput_2[] = "1235\b456.\n";
+const char ExpectedInput_3[] = "tab\ttab.\n";
+const char ExpectedInput_4[] = "cr\r.\n";
+const char ExpectedInput_5[] = "aBcDeFgH.\n";
+
+static void
+test_main(void)
+{
+  open_it();
+
+  /* some basic cases */
+  write_helper( Test_fd, ExpectedOutput_1 );
+  read_helper( Test_fd, ExpectedOutput_1 );
+  write_helper( Test_fd, ExpectedInput_1 );
+  read_helper( Test_fd, ExpectedInput_1 );
+  write_helper( Test_fd, ExpectedInput_2 );
+  read_helper( Test_fd, ExpectedInput_2 );
+  write_helper( Test_fd, ExpectedInput_3 );
+  read_helper( Test_fd, ExpectedInput_3 );
+  write_helper( Test_fd, ExpectedInput_4 );
+  read_helper( Test_fd, ExpectedInput_4 );
+
+  /* test to lower case input mapping */
+  write_helper( Test_fd, ExpectedInput_5 );
+  read_helper( Test_fd, ExpectedInput_5 );
+	//IUCLC is not supported within FREEBSD so this should not change the output
+  change_iflag( "Enable to lower case mapping on input", IUCLC, IUCLC );
+  write_helper( Test_fd, ExpectedInput_5 );
+  read_helper( Test_fd, ExpectedInput_5 );
+  change_iflag( "Disable to lower case mapping on input", IUCLC, 0 );
+
+  close_it();
+
+	exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial05/test_main.c b/testsuite/usbserial05/test_main.c
new file mode 100755
index 0000000..7e657ff
--- /dev/null
+++ b/testsuite/usbserial05/test_main.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires an external program with Xon/Xoff Flow control enabled.
+ * The external program should monitor the number of bytes received and transmitted
+ * to verify no bytes were drop.  Using the USB serial device with a loopback plug
+ * not not seem to work.
+ */
+
+#include <machine/rtems-bsd-kernel-space.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <sys/systm.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <sys/_termios.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 5"
+//#define USE_LOOPBACK_TEST
+
+/**
+ *  This macro defines the standard name for the USB serial device
+ *  that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+#define PRIO_READ  (RTEMS_MAXIMUM_PRIORITY - 3)
+#define USB_SERIAL_XON_BUFFER_WRITES	25
+
+void write_helper(int fd, const char *c);
+void read_helper(int fd, const char *expected);
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+void change_vmin_vtime( const char *desc, int min, int time );
+
+static rtems_id rid;
+static volatile bool kill_rtask;
+static volatile bool rtask_active;
+static volatile int bytes_written;
+static volatile int bytes_read;
+
+void write_helper(
+  int        fd,
+  const char *c
+)
+{
+  size_t   len;
+  int      rc;
+
+  len = strlen( c );
+
+  rc = write( fd, c, len );
+  assert( rc == len );
+
+	bytes_written += rc;
+}
+
+const char ExpectedInput_1[] = "Blocking interrupt driven read.\n";
+uint8_t read_helper_buffer[256];
+
+void read_helper(
+  int         fd,
+  const char *expected
+)
+{
+  int    rc;
+
+  rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) );
+  assert( rc != -1 );
+
+	bytes_read += rc;
+}
+
+int Test_fd;
+
+void open_it(void)
+{
+  int end_time;
+
+  puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  Test_fd = -1;
+  end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+  while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+    Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    if(Test_fd == -1) {
+      puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+    }
+  }
+  assert( Test_fd != -1 );
+
+	change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+	change_lflag("", ECHO|ECHONL|ICANON|ISIG|IEXTEN, 0);
+	change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+  int rc;
+
+  puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  rc = close( Test_fd );
+  assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_iflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_iflag &= ~mask;
+  attr.c_iflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_lflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_lflag &= ~mask;
+  attr.c_lflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_oflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_oflag &= ~mask;
+  attr.c_oflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_vmin_vtime( const char *desc, int min, int time )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing %s - VMIN=%d VTIME=%d\n", desc, min, time );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_cc[VMIN] = min;
+  attr.c_cc[VTIME] = time;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+const char ExpectedOutput_1[] =
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789\r\n";
+
+static void
+usb_serial_read_task(rtems_task_argument arg)
+{
+	int i;
+  int end_time;
+
+  rtask_active = true;
+  kill_rtask = false;
+	printf( "Read Begin\n");
+	i = 0;
+  change_vmin_vtime( "to 5 second timeout", 0, 50 );
+	end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(30000);
+  while(!kill_rtask && (rtems_clock_get_ticks_since_boot() < end_time)) {
+  	read_helper( Test_fd, ExpectedOutput_1 );
+		i++;
+  	printf( "%d: Bytes Read: %d\n", i, bytes_read );
+	}
+	printf( "Read End\n");
+  rtask_active = false;
+
+	rtems_task_delete(RTEMS_SELF);
+}
+
+static void
+test_main(void)
+{
+  rtems_status_code sc;
+	int i;
+  int end_time;
+
+	bytes_written = 0;
+	bytes_read = 0;
+
+	open_it();
+
+  change_iflag( "Set XON/XOFF", IXON|IXOFF, IXON|IXOFF );
+
+#ifdef USE_LOOPBACK_TEST
+  sc = rtems_task_create(
+    rtems_build_name('U', 'S', 'B', 'R'),
+    PRIO_READ,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_FLOATING_POINT,
+    &rid
+  );
+  assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(rid, usb_serial_read_task, NULL);
+  assert(sc == RTEMS_SUCCESSFUL);
+
+	rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(250));
+#endif
+
+	printf( "Write Begin\n");
+	for(i = 0; i < USB_SERIAL_XON_BUFFER_WRITES; i++) {
+  	write_helper( Test_fd, ExpectedOutput_1 );
+  	printf( "%d: Bytes Written: %d\n", i, bytes_written );
+	}
+	printf( "Write End\n");
+
+#ifndef USE_LOOPBACK_TEST
+	printf( "Read Begin\n");
+	i = 0;
+  change_vmin_vtime( "to 5 second timeout", 0, 50 );
+	end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(30000);
+  while(rtems_clock_get_ticks_since_boot() < end_time) {
+  	read_helper( Test_fd, ExpectedOutput_1 );
+		i++;
+  	printf( "%d: Bytes Read: %d\n", i, bytes_read );
+	}
+	printf( "Read End\n");
+#else
+  //kill_rtask = true;
+  while(rtask_active)
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(100));
+  }
+#endif
+
+	close_it();
+
+	exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial06/test_main.c b/testsuite/usbserial06/test_main.c
new file mode 100755
index 0000000..bb7aa13
--- /dev/null
+++ b/testsuite/usbserial06/test_main.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 6"
+
+/**
+ *  This macro defines the standard name for the USB serial device
+ *  that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void open_it(void);
+void close_it(void);
+void write_it( const char *data );
+void read_it( ssize_t expected, ssize_t lookfor );
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+void change_vmin_vtime( const char *desc, int min, int time );
+
+int Test_fd;
+
+void open_it(void)
+{
+  int end_time;
+
+  puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  Test_fd = -1;
+  end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+  while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+  {
+    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+    Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+    if(Test_fd == -1) {
+      puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+    }
+  }
+  assert( Test_fd != -1 );
+
+	change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+	change_lflag("", ECHO|ECHONL|ICANON|ISIG|IEXTEN, 0);
+	change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+  int rc;
+
+  puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+  rc = close( Test_fd );
+  assert( rc == 0 );
+}
+
+void write_it( const char *data )
+{
+  ssize_t sc;
+	ssize_t len = strlen( data );
+
+  puts( "write() - OK " );
+  sc = write(Test_fd, data, len);
+  assert( sc == len );
+}
+
+void read_it( ssize_t expected, ssize_t lookfor )
+{
+  ssize_t rc, ii, jj;
+  char    buf[32];
+
+  assert( lookfor <= sizeof(buf) );
+
+  printf( "read - %zd expected\n", expected );
+  rc = read( Test_fd, buf, lookfor );
+  if ( expected != rc )
+    printf( "ERROR - expected=%zd rc=%zd\n", expected, rc );
+  assert( expected == rc );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_iflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_iflag &= ~mask;
+  attr.c_iflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_lflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_lflag &= ~mask;
+  attr.c_lflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing c_oflag to: %s\n", desc );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_oflag &= ~mask;
+  attr.c_oflag |= new;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+void change_vmin_vtime( const char *desc, int min, int time )
+{
+  int            rc;
+  struct termios attr;
+
+  printf( "Changing %s - VMIN=%d VTIME=%d\n", desc, min, time );
+  rc = tcgetattr( Test_fd, &attr );
+  assert( rc == 0 );
+
+  attr.c_cc[VMIN] = min;
+  attr.c_cc[VTIME] = time;
+
+  rc = tcsetattr( Test_fd, TCSANOW, &attr );
+  assert( rc == 0 );
+}
+
+static void
+test_main(void)
+{
+  open_it();
+
+  change_vmin_vtime( "to polling", 0, 0 );
+  read_it( 0, 10 );
+
+  change_vmin_vtime( "to 5 second timeout", 0, 50 );
+  read_it( 0, 10 );
+
+  change_vmin_vtime( "to 5 second timeout", 5, 50 );
+  puts( "Enqueue 2 characters" );
+  write_it( "ab" );
+  read_it( 2, 10 );
+
+	puts( "Enqueue 7 characters" );
+  write_it( "1234567" );
+  read_it( 5, 5 );
+  read_it( 2, 2 );
+
+  close_it();
+
+	exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
-- 
1.9.1



More information about the devel mailing list