Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:46

0001 /*
0002  * Console driver for Motorola MCF5206E UART modules
0003  */
0004 
0005 /*
0006  * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
0007  * Author: Victor V. Vengerov <vvv@oktet.ru>
0008  *
0009  *  COPYRIGHT (c) 1989-1998.
0010  *  On-Line Applications Research Corporation (OAR).
0011  *
0012  *  The license and distribution terms for this file may be
0013  *  found in the file LICENSE in this distribution or at
0014  *  http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #include <termios.h>
0018 #include <bsp.h>
0019 #include <rtems/libio.h>
0020 #include <rtems/console.h>
0021 #include "mcf5206/mcf5206e.h"
0022 #include "mcf5206/mcfuart.h"
0023 
0024 /* Descriptor structures for two on-chip UART channels */
0025 static mcfuart uart[2];
0026 
0027 /* Console operations mode:
0028  *     0 - raw (non-termios) polled input/output
0029  *     1 - termios-based polled input/output
0030  *     2 - termios-based interrupt-driven input/output
0031  */
0032 int console_mode = 2;
0033 #define CONSOLE_MODE_RAW  (0)
0034 #define CONSOLE_MODE_POLL (1)
0035 #define CONSOLE_MODE_INT  (2)
0036 
0037 /* Wrapper functions for MCF UART generic driver */
0038 
0039 /* console_poll_read --
0040  *     wrapper for poll read function
0041  *
0042  * PARAMETERS:
0043  *     minor - minor device number
0044  *
0045  * RETURNS:
0046  *     character code readed from UART, or -1 if there is no characters
0047  *     available
0048  */
0049 static int
0050 console_poll_read(int minor)
0051 {
0052   return mcfuart_poll_read(&uart[minor]);
0053 }
0054 
0055 /* console_interrupt_write --
0056  *     wrapper for interrupt write function
0057  *
0058  * PARAMETERS:
0059  *     minor - minor device number
0060  *     buf - output buffer
0061  *     len - output buffer length
0062  *
0063  * RETURNS:
0064  *     result code
0065  */
0066 static ssize_t
0067 console_interrupt_write(int minor, const char *buf, size_t len)
0068 {
0069   return mcfuart_interrupt_write(&uart[minor], buf, len);
0070 }
0071 
0072 /* console_poll_write --
0073  *     wrapper for polling mode write function
0074  *
0075  * PARAMETERS:
0076  *     minor - minor device number
0077  *     buf - output buffer
0078  *     len - output buffer length
0079  *
0080  * RETURNS:
0081  *     result code
0082  */
0083 static ssize_t
0084 console_poll_write(int minor, const char *buf, size_t len)
0085 {
0086   return mcfuart_poll_write(&uart[minor], buf, len);
0087 }
0088 
0089 /* console_set_attributes --
0090  *     wrapper for hardware-dependent termios attributes setting
0091  *
0092  * PARAMETERS:
0093  *     minor - minor device number
0094  *     t - pointer to the termios structure
0095  *
0096  * RETURNS:
0097  *     result code
0098  */
0099 static int
0100 console_set_attributes(int minor, const struct termios *t)
0101 {
0102   return mcfuart_set_attributes(&uart[minor], t);
0103 }
0104 
0105 /* console_stop_remote_tx --
0106  *     wrapper for stopping data flow from remote party.
0107  *
0108  * PARAMETERS:
0109  *     minor - minor device number
0110  *
0111  * RETURNS:
0112  *     result code
0113  */
0114 static int
0115 console_stop_remote_tx(int minor)
0116 {
0117   if (minor < sizeof(uart)/sizeof(uart[0]))
0118     return mcfuart_stop_remote_tx(&uart[minor]);
0119   else
0120     return RTEMS_INVALID_NUMBER;
0121 }
0122 
0123 /* console_start_remote_tx --
0124  *     wrapper for resuming data flow from remote party.
0125  *
0126  * PARAMETERS:
0127  *     minor - minor device number
0128  *
0129  */
0130 static int
0131 console_start_remote_tx(int minor)
0132 {
0133   if (minor < sizeof(uart)/sizeof(uart[0]))
0134     return mcfuart_start_remote_tx(&uart[minor]);
0135   else
0136     return RTEMS_INVALID_NUMBER;
0137 }
0138 
0139 /* console_first_open --
0140  *     wrapper for UART controller initialization functions
0141  *
0142  * PARAMETERS:
0143  *     major - major device number
0144  *     minor - minor device number
0145  *     arg - libio device open argument
0146  *
0147  * RETURNS:
0148  *     error code
0149  */
0150 static int
0151 console_first_open(int major, int minor, void *arg)
0152 {
0153   rtems_libio_open_close_args_t *args = arg;
0154   rtems_status_code sc;
0155   uint8_t         intvec;
0156 
0157   switch (minor) {
0158     case 0: intvec = BSP_INTVEC_UART1; break;
0159     case 1: intvec = BSP_INTVEC_UART2; break;
0160     default:
0161       return RTEMS_INVALID_NUMBER;
0162   }
0163 
0164   if (console_mode != CONSOLE_MODE_INT) {
0165     intvec = 0;
0166   }
0167 
0168   sc = mcfuart_init(
0169     &uart[minor],          /* uart */
0170     args->iop->data1,      /* tty */
0171     intvec,                /* interrupt vector number */
0172     minor+1);
0173 
0174   if (sc == RTEMS_SUCCESSFUL)
0175     sc = mcfuart_reset(&uart[minor]);
0176 
0177   return sc;
0178 }
0179 
0180 /* console_last_close --
0181  *     wrapper for UART controller close function
0182  *
0183  * PARAMETERS:
0184  *     major - major device number
0185  *     minor - minor device number
0186  *     arg - libio device close argument
0187  *
0188  * RETURNS:
0189  *     error code
0190  */
0191 static int
0192 console_last_close(int major, int minor, void *arg)
0193 {
0194   return mcfuart_disable(&uart[minor]);
0195 }
0196 
0197 /* console_initialize --
0198  *     This routine initializes the console IO drivers and register devices
0199  *     in RTEMS I/O system.
0200  *
0201  * PARAMETERS:
0202  *     major - major console device number
0203  *     minor - minor console device number (not used)
0204  *     arg - device initialize argument
0205  *
0206  * RETURNS:
0207  *     RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
0208  */
0209 rtems_device_driver console_initialize(
0210   rtems_device_major_number major,
0211   rtems_device_minor_number minor,
0212   void *arg)
0213 {
0214   rtems_status_code status;
0215 
0216   /*
0217    * Set up TERMIOS
0218    */
0219   if (console_mode != CONSOLE_MODE_RAW)
0220       rtems_termios_initialize ();
0221 
0222   /*
0223    * Register the devices
0224    */
0225   status = rtems_io_register_name ("/dev/console", major, 0);
0226   if (status != RTEMS_SUCCESSFUL)
0227     rtems_fatal_error_occurred (status);
0228 
0229   status = rtems_io_register_name ("/dev/aux", major, 1);
0230   if (status != RTEMS_SUCCESSFUL)
0231     rtems_fatal_error_occurred (status);
0232 
0233   if (console_mode == CONSOLE_MODE_RAW) {
0234     rtems_status_code sc;
0235     sc = mcfuart_init(&uart[0],              /* uart */
0236                       NULL,                  /* tty */
0237                       0,                     /* interrupt vector number */
0238                       1);                    /* UART channel number */
0239 
0240     if (sc == RTEMS_SUCCESSFUL)
0241         sc = mcfuart_reset(&uart[0]);
0242 
0243     sc = mcfuart_init(&uart[1],              /* uart */
0244                       NULL,                  /* tty */
0245                       0,                     /* interrupt vector number */
0246                       2);                    /* UART channel number */
0247 
0248     if (sc == RTEMS_SUCCESSFUL)
0249       sc = mcfuart_reset(&uart[1]);
0250     return sc;
0251   }
0252 
0253   return RTEMS_SUCCESSFUL;
0254 }
0255 
0256 /* console_open --
0257  *     Open console device driver. Pass appropriate termios callback
0258  *     functions to termios library.
0259  *
0260  * PARAMETERS:
0261  *     major - major device number for console devices
0262  *     minor - minor device number for console
0263  *     arg - device opening argument
0264  *
0265  * RETURNS:
0266  *     RTEMS error code
0267  */
0268 rtems_device_driver
0269 console_open(rtems_device_major_number major,
0270              rtems_device_minor_number minor,
0271              void *arg)
0272 {
0273   static const rtems_termios_callbacks intr_callbacks = {
0274     console_first_open,        /* firstOpen */
0275     console_last_close,        /* lastClose */
0276     NULL,                      /* pollRead */
0277     console_interrupt_write,   /* write */
0278     console_set_attributes,    /* setAttributes */
0279     console_stop_remote_tx,    /* stopRemoteTx */
0280     console_start_remote_tx,   /* startRemoteTx */
0281     TERMIOS_IRQ_DRIVEN         /* outputUsesInterrupts */
0282   };
0283   static const rtems_termios_callbacks poll_callbacks = {
0284     console_first_open,        /* firstOpen */
0285     console_last_close,        /* lastClose */
0286     console_poll_read,         /* pollRead */
0287     console_poll_write,        /* write */
0288     console_set_attributes,    /* setAttributes */
0289     console_stop_remote_tx,    /* stopRemoteTx */
0290     console_start_remote_tx,   /* startRemoteTx */
0291     TERMIOS_POLLED             /* outputUsesInterrupts */
0292   };
0293 
0294   switch (console_mode) {
0295     case CONSOLE_MODE_RAW:
0296       return RTEMS_SUCCESSFUL;
0297 
0298     case CONSOLE_MODE_INT:
0299       return rtems_termios_open(major, minor, arg, &intr_callbacks);
0300 
0301       case CONSOLE_MODE_POLL:
0302         return rtems_termios_open(major, minor, arg, &poll_callbacks);
0303 
0304       default:
0305         rtems_fatal_error_occurred(0xC07A1310);
0306   }
0307   return RTEMS_INTERNAL_ERROR;
0308 }
0309 
0310 /* console_close --
0311  *     Close console device.
0312  *
0313  * PARAMETERS:
0314  *     major - major device number for console devices
0315  *     minor - minor device number for console
0316  *     arg - device close argument
0317  *
0318  * RETURNS:
0319  *     RTEMS error code
0320  */
0321 rtems_device_driver
0322 console_close(rtems_device_major_number major,
0323               rtems_device_minor_number minor,
0324               void *arg)
0325 {
0326   if (console_mode != CONSOLE_MODE_RAW)
0327     return rtems_termios_close (arg);
0328   else
0329     return RTEMS_SUCCESSFUL;
0330 }
0331 
0332 /* console_read --
0333  *     Read from the console device
0334  *
0335  * PARAMETERS:
0336  *     major - major device number for console devices
0337  *     minor - minor device number for console
0338  *     arg - device read argument
0339  *
0340  * RETURNS:
0341  *     RTEMS error code
0342  */
0343 rtems_device_driver
0344 console_read(rtems_device_major_number major,
0345              rtems_device_minor_number minor,
0346              void *arg)
0347 {
0348   if (console_mode != CONSOLE_MODE_RAW) {
0349     return rtems_termios_read (arg);
0350   } else {
0351     rtems_libio_rw_args_t *argp = arg;
0352     char *buf = argp->buffer;
0353     int count = argp->count;
0354     int n = 0;
0355     int c;
0356 
0357     while (n < count) {
0358       do {
0359         c = mcfuart_poll_read(&uart[minor]);
0360       } while (c == -1);
0361       if (c == '\r')
0362         c = '\n';
0363       *(buf++) = c;
0364       n++;
0365       if (c == '\n')
0366         break;
0367     }
0368     argp->bytes_moved = n;
0369     return RTEMS_SUCCESSFUL;
0370   }
0371 }
0372 
0373 /* console_write --
0374  *     Write to the console device
0375  *
0376  * PARAMETERS:
0377  *     major - major device number for console devices
0378  *     minor - minor device number for console
0379  *     arg - device write argument
0380  *
0381  * RETURNS:
0382  *     RTEMS error code
0383  */
0384 rtems_device_driver
0385 console_write(rtems_device_major_number major,
0386               rtems_device_minor_number minor,
0387               void *arg
0388 )
0389 {
0390   if (console_mode != CONSOLE_MODE_RAW) {
0391     return rtems_termios_write (arg);
0392   } else {
0393     rtems_libio_rw_args_t *argp = arg;
0394     char cr = '\r';
0395     char *buf = argp->buffer;
0396     int count = argp->count;
0397     int i;
0398 
0399     for (i = 0; i < count; i++) {
0400         if (*buf == '\n')
0401             mcfuart_poll_write(&uart[minor], &cr, 1);
0402         mcfuart_poll_write(&uart[minor], buf, 1);
0403         buf++;
0404     }
0405     argp->bytes_moved = count;
0406     return RTEMS_SUCCESSFUL;
0407   }
0408 }
0409 
0410 /* console_control --
0411  *     Handle console device I/O control (IOCTL)
0412  *
0413  * PARAMETERS:
0414  *     major - major device number for console devices
0415  *     minor - minor device number for console
0416  *     arg - device ioctl argument
0417  *
0418  * RETURNS:
0419  *     RTEMS error code
0420  */
0421 rtems_device_driver
0422 console_control(rtems_device_major_number major,
0423                 rtems_device_minor_number minor,
0424                 void *arg)
0425 {
0426   if (console_mode != CONSOLE_MODE_RAW) {
0427     return rtems_termios_ioctl (arg);
0428   } else {
0429     return RTEMS_SUCCESSFUL;
0430   }
0431 }