Index: bsps/m68k/mcf5206elite/console/console.c
===================================================================
--- bsps/m68k/mcf5206elite/console/console.c	(revision d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc)
+++ bsps/m68k/mcf5206elite/console/console.c	(revision d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc)
@@ -0,0 +1,431 @@
+/*
+ * Console driver for Motorola MCF5206E UART modules
+ */
+
+/*
+ * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ *  COPYRIGHT (c) 1989-1998.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <termios.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <rtems/console.h>
+#include "mcf5206/mcf5206e.h"
+#include "mcf5206/mcfuart.h"
+
+/* Descriptor structures for two on-chip UART channels */
+static mcfuart uart[2];
+
+/* Console operations mode:
+ *     0 - raw (non-termios) polled input/output
+ *     1 - termios-based polled input/output
+ *     2 - termios-based interrupt-driven input/output
+ */
+int console_mode = 2;
+#define CONSOLE_MODE_RAW  (0)
+#define CONSOLE_MODE_POLL (1)
+#define CONSOLE_MODE_INT  (2)
+
+/* Wrapper functions for MCF UART generic driver */
+
+/* console_poll_read --
+ *     wrapper for poll read function
+ *
+ * PARAMETERS:
+ *     minor - minor device number
+ *
+ * RETURNS:
+ *     character code readed from UART, or -1 if there is no characters
+ *     available
+ */
+static int
+console_poll_read(int minor)
+{
+  return mcfuart_poll_read(&uart[minor]);
+}
+
+/* console_interrupt_write --
+ *     wrapper for interrupt write function
+ *
+ * PARAMETERS:
+ *     minor - minor device number
+ *     buf - output buffer
+ *     len - output buffer length
+ *
+ * RETURNS:
+ *     result code
+ */
+static ssize_t
+console_interrupt_write(int minor, const char *buf, size_t len)
+{
+  return mcfuart_interrupt_write(&uart[minor], buf, len);
+}
+
+/* console_poll_write --
+ *     wrapper for polling mode write function
+ *
+ * PARAMETERS:
+ *     minor - minor device number
+ *     buf - output buffer
+ *     len - output buffer length
+ *
+ * RETURNS:
+ *     result code
+ */
+static ssize_t
+console_poll_write(int minor, const char *buf, size_t len)
+{
+  return mcfuart_poll_write(&uart[minor], buf, len);
+}
+
+/* console_set_attributes --
+ *     wrapper for hardware-dependent termios attributes setting
+ *
+ * PARAMETERS:
+ *     minor - minor device number
+ *     t - pointer to the termios structure
+ *
+ * RETURNS:
+ *     result code
+ */
+static int
+console_set_attributes(int minor, const struct termios *t)
+{
+  return mcfuart_set_attributes(&uart[minor], t);
+}
+
+/* console_stop_remote_tx --
+ *     wrapper for stopping data flow from remote party.
+ *
+ * PARAMETERS:
+ *     minor - minor device number
+ *
+ * RETURNS:
+ *     result code
+ */
+static int
+console_stop_remote_tx(int minor)
+{
+  if (minor < sizeof(uart)/sizeof(uart[0]))
+    return mcfuart_stop_remote_tx(&uart[minor]);
+  else
+    return RTEMS_INVALID_NUMBER;
+}
+
+/* console_start_remote_tx --
+ *     wrapper for resuming data flow from remote party.
+ *
+ * PARAMETERS:
+ *     minor - minor device number
+ *
+ */
+static int
+console_start_remote_tx(int minor)
+{
+  if (minor < sizeof(uart)/sizeof(uart[0]))
+    return mcfuart_start_remote_tx(&uart[minor]);
+  else
+    return RTEMS_INVALID_NUMBER;
+}
+
+/* console_first_open --
+ *     wrapper for UART controller initialization functions
+ *
+ * PARAMETERS:
+ *     major - major device number
+ *     minor - minor device number
+ *     arg - libio device open argument
+ *
+ * RETURNS:
+ *     error code
+ */
+static int
+console_first_open(int major, int minor, void *arg)
+{
+  rtems_libio_open_close_args_t *args = arg;
+  rtems_status_code sc;
+  uint8_t         intvec;
+
+  switch (minor) {
+    case 0: intvec = BSP_INTVEC_UART1; break;
+    case 1: intvec = BSP_INTVEC_UART2; break;
+    default:
+      return RTEMS_INVALID_NUMBER;
+  }
+
+  if (console_mode != CONSOLE_MODE_INT) {
+    intvec = 0;
+  }
+
+  sc = mcfuart_init(
+    &uart[minor],          /* uart */
+    args->iop->data1,      /* tty */
+    intvec,                /* interrupt vector number */
+    minor+1);
+
+  if (sc == RTEMS_SUCCESSFUL)
+    sc = mcfuart_reset(&uart[minor]);
+
+  return sc;
+}
+
+/* console_last_close --
+ *     wrapper for UART controller close function
+ *
+ * PARAMETERS:
+ *     major - major device number
+ *     minor - minor device number
+ *     arg - libio device close argument
+ *
+ * RETURNS:
+ *     error code
+ */
+static int
+console_last_close(int major, int minor, void *arg)
+{
+  return mcfuart_disable(&uart[minor]);
+}
+
+/* console_initialize --
+ *     This routine initializes the console IO drivers and register devices
+ *     in RTEMS I/O system.
+ *
+ * PARAMETERS:
+ *     major - major console device number
+ *     minor - minor console device number (not used)
+ *     arg - device initialize argument
+ *
+ * RETURNS:
+ *     RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
+ */
+rtems_device_driver console_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *arg)
+{
+  rtems_status_code status;
+
+  /*
+   * Set up TERMIOS
+   */
+  if (console_mode != CONSOLE_MODE_RAW)
+      rtems_termios_initialize ();
+
+  /*
+   * Register the devices
+   */
+  status = rtems_io_register_name ("/dev/console", major, 0);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+
+  status = rtems_io_register_name ("/dev/aux", major, 1);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+
+  if (console_mode == CONSOLE_MODE_RAW) {
+    rtems_status_code sc;
+    sc = mcfuart_init(&uart[0],              /* uart */
+                      NULL,                  /* tty */
+                      0,                     /* interrupt vector number */
+                      1);                    /* UART channel number */
+
+    if (sc == RTEMS_SUCCESSFUL)
+        sc = mcfuart_reset(&uart[0]);
+
+    sc = mcfuart_init(&uart[1],              /* uart */
+                      NULL,                  /* tty */
+                      0,                     /* interrupt vector number */
+                      2);                    /* UART channel number */
+
+    if (sc == RTEMS_SUCCESSFUL)
+      sc = mcfuart_reset(&uart[1]);
+    return sc;
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+/* console_open --
+ *     Open console device driver. Pass appropriate termios callback
+ *     functions to termios library.
+ *
+ * PARAMETERS:
+ *     major - major device number for console devices
+ *     minor - minor device number for console
+ *     arg - device opening argument
+ *
+ * RETURNS:
+ *     RTEMS error code
+ */
+rtems_device_driver
+console_open(rtems_device_major_number major,
+             rtems_device_minor_number minor,
+             void *arg)
+{
+  static const rtems_termios_callbacks intr_callbacks = {
+    console_first_open,        /* firstOpen */
+    console_last_close,        /* lastClose */
+    NULL,                      /* pollRead */
+    console_interrupt_write,   /* write */
+    console_set_attributes,    /* setAttributes */
+    console_stop_remote_tx,    /* stopRemoteTx */
+    console_start_remote_tx,   /* startRemoteTx */
+    1                          /* outputUsesInterrupts */
+  };
+  static const rtems_termios_callbacks poll_callbacks = {
+    console_first_open,        /* firstOpen */
+    console_last_close,        /* lastClose */
+    console_poll_read,         /* pollRead */
+    console_poll_write,        /* write */
+    console_set_attributes,    /* setAttributes */
+    console_stop_remote_tx,    /* stopRemoteTx */
+    console_start_remote_tx,   /* startRemoteTx */
+    0                          /* outputUsesInterrupts */
+  };
+
+  switch (console_mode) {
+    case CONSOLE_MODE_RAW:
+      return RTEMS_SUCCESSFUL;
+
+    case CONSOLE_MODE_INT:
+      return rtems_termios_open(major, minor, arg, &intr_callbacks);
+
+      case CONSOLE_MODE_POLL:
+        return rtems_termios_open(major, minor, arg, &poll_callbacks);
+
+      default:
+        rtems_fatal_error_occurred(0xC07A1310);
+  }
+  return RTEMS_INTERNAL_ERROR;
+}
+
+/* console_close --
+ *     Close console device.
+ *
+ * PARAMETERS:
+ *     major - major device number for console devices
+ *     minor - minor device number for console
+ *     arg - device close argument
+ *
+ * RETURNS:
+ *     RTEMS error code
+ */
+rtems_device_driver
+console_close(rtems_device_major_number major,
+              rtems_device_minor_number minor,
+              void *arg)
+{
+  if (console_mode != CONSOLE_MODE_RAW)
+    return rtems_termios_close (arg);
+  else
+    return RTEMS_SUCCESSFUL;
+}
+
+/* console_read --
+ *     Read from the console device
+ *
+ * PARAMETERS:
+ *     major - major device number for console devices
+ *     minor - minor device number for console
+ *     arg - device read argument
+ *
+ * RETURNS:
+ *     RTEMS error code
+ */
+rtems_device_driver
+console_read(rtems_device_major_number major,
+             rtems_device_minor_number minor,
+             void *arg)
+{
+  if (console_mode != CONSOLE_MODE_RAW) {
+    return rtems_termios_read (arg);
+  } else {
+    rtems_libio_rw_args_t *argp = arg;
+    char *buf = argp->buffer;
+    int count = argp->count;
+    int n = 0;
+    int c;
+
+    while (n < count) {
+      do {
+        c = mcfuart_poll_read(&uart[minor]);
+      } while (c == -1);
+      if (c == '\r')
+        c = '\n';
+      *(buf++) = c;
+      n++;
+      if (c == '\n')
+        break;
+    }
+    argp->bytes_moved = n;
+    return RTEMS_SUCCESSFUL;
+  }
+}
+
+/* console_write --
+ *     Write to the console device
+ *
+ * PARAMETERS:
+ *     major - major device number for console devices
+ *     minor - minor device number for console
+ *     arg - device write argument
+ *
+ * RETURNS:
+ *     RTEMS error code
+ */
+rtems_device_driver
+console_write(rtems_device_major_number major,
+              rtems_device_minor_number minor,
+              void *arg
+)
+{
+  if (console_mode != CONSOLE_MODE_RAW) {
+    return rtems_termios_write (arg);
+  } else {
+    rtems_libio_rw_args_t *argp = arg;
+    char cr = '\r';
+    char *buf = argp->buffer;
+    int count = argp->count;
+    int i;
+
+    for (i = 0; i < count; i++) {
+        if (*buf == '\n')
+            mcfuart_poll_write(&uart[minor], &cr, 1);
+        mcfuart_poll_write(&uart[minor], buf, 1);
+        buf++;
+    }
+    argp->bytes_moved = count;
+    return RTEMS_SUCCESSFUL;
+  }
+}
+
+/* console_control --
+ *     Handle console device I/O control (IOCTL)
+ *
+ * PARAMETERS:
+ *     major - major device number for console devices
+ *     minor - minor device number for console
+ *     arg - device ioctl argument
+ *
+ * RETURNS:
+ *     RTEMS error code
+ */
+rtems_device_driver
+console_control(rtems_device_major_number major,
+                rtems_device_minor_number minor,
+                void *arg)
+{
+  if (console_mode != CONSOLE_MODE_RAW) {
+    return rtems_termios_ioctl (arg);
+  } else {
+    return RTEMS_SUCCESSFUL;
+  }
+}
