Back to home page

LXR

 
 

    


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

0001  /*
0002   *  Multi UART console serial I/O.
0003   *
0004   * TO DO: Add DMA input/output
0005   */
0006 
0007 #include <stdio.h>
0008 #include <fcntl.h>
0009 #include <termios.h>
0010 #include <malloc.h>
0011 
0012 #include <rtems/libio.h>
0013 #include <rtems/termiostypes.h>
0014 #include <rtems/console.h>
0015 #include <rtems/bspIo.h>
0016 
0017 #include <bsp.h>
0018 
0019 #define UART_INTC0_IRQ_VECTOR(x) (64+26+(x))
0020 
0021 #define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \
0022                              MCF_UART_USR_FE | \
0023                              MCF_UART_USR_PE | \
0024                              MCF_UART_USR_OE )
0025 
0026 static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
0027 static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len);
0028 
0029 static void _BSP_null_char(char c)
0030 {
0031   int level;
0032 
0033   rtems_interrupt_disable(level);
0034   while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0)
0035     continue;
0036   MCF_UART_UTB(CONSOLE_PORT) = c;
0037   while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0)
0038     continue;
0039   rtems_interrupt_enable(level);
0040 }
0041 
0042 BSP_output_char_function_type     BSP_output_char = _BSP_null_char;
0043 BSP_polling_getchar_function_type BSP_poll_char = NULL;
0044 
0045 #define MAX_UART_INFO     3
0046 #define RX_BUFFER_SIZE    512
0047 
0048 struct IntUartInfoStruct
0049 {
0050   int iomode;
0051   volatile int uimr;
0052   int baud;
0053   int databits;
0054   int parity;
0055   int stopbits;
0056   int hwflow;
0057   int rx_in;
0058   int rx_out;
0059   char rx_buffer[RX_BUFFER_SIZE];
0060   void *ttyp;
0061 };
0062 
0063 struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
0064 
0065 /***************************************************************************
0066    Function : IntUartSet
0067 
0068    Description : This updates the hardware UART settings.
0069  ***************************************************************************/
0070 static void
0071 IntUartSet(int minor, int baud, int databits, int parity, int stopbits,
0072            int hwflow)
0073 {
0074   int divisor;
0075   uint32_t clock_speed;
0076   uint8_t umr1 = 0;
0077   uint8_t umr2 = 0;
0078   struct IntUartInfoStruct *info = &IntUartInfo[minor];
0079   int level;
0080 
0081   rtems_interrupt_disable(level);
0082 
0083   /* disable interrupts, clear RTS line, and disable the UARTS */
0084   MCF_UART_UIMR(minor) = 0;
0085   MCF_UART_UOP0(minor) = 1;
0086   MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
0087 
0088   /* save the current values */
0089   info->uimr = 0;
0090   info->baud = baud;
0091   info->databits = databits;
0092   info->parity = parity;
0093   info->stopbits = stopbits;
0094   info->hwflow = hwflow;
0095 
0096   clock_speed = bsp_get_BUS_clock_speed();
0097   /* determine the baud divisor value */
0098   divisor = ((clock_speed) / (32 * baud));
0099   if (divisor < 2)
0100     divisor = 2;
0101 
0102   /* check to see if doing hardware flow control */
0103   if (hwflow) {
0104     /* set hardware flow options */
0105     umr1 |= MCF_UART_UMR_RXRTS;
0106     umr2 |= MCF_UART_UMR_TXCTS;
0107   }
0108 
0109   /* determine the new umr values */
0110   umr1 |= (parity | databits);
0111   umr2 |= (stopbits);
0112 
0113   /* reset the uart */
0114   MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR;
0115   MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX;
0116   MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX;
0117 
0118   /* reset the uart mode register and update values */
0119   MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR;
0120   MCF_UART_UMR(minor) = umr1;
0121   MCF_UART_UMR(minor) = umr2;
0122 
0123   /* set the baud rate values */
0124   MCF_UART_UCSR(minor) =
0125     (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK);
0126   MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
0127   MCF_UART_UBG2(minor) = (divisor & 0x00ff);
0128 
0129   /* enable the uart */
0130   MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
0131 
0132   /* check to see if interrupts need to be enabled */
0133   if (info->iomode != TERMIOS_POLLED) {
0134     /* enable rx interrupts */
0135     info->uimr |= MCF_UART_UIMR_RXRDY_FU;
0136     MCF_UART_UIMR(minor) = info->uimr;
0137   }
0138 
0139   /* check to see if doing hardware flow control */
0140   if (hwflow) {
0141     /* assert the RTS line */
0142     MCF_UART_UOP1(minor) = 1;
0143   }
0144 
0145   rtems_interrupt_enable(level);
0146 
0147 }
0148 
0149 /***************************************************************************
0150    Function : IntUartSetAttributes
0151 
0152    Description : This provides the hardware-dependent portion of tcsetattr().
0153    value and sets it. At the moment this just sets the baud rate.
0154 
0155    Note: The highest baudrate is 115200 as this stays within
0156    an error of +/- 5% at 25MHz processor clock
0157  ***************************************************************************/
0158 static int IntUartSetAttributes(int minor, const struct termios *t)
0159 {
0160   /* set default index values */
0161   int baud = (int) 19200;
0162   int databits = (int) MCF_UART_UMR_BC_8;
0163   int parity = (int) MCF_UART_UMR_PM_NONE;
0164   int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1;
0165   int hwflow = (int) 0;
0166   struct IntUartInfoStruct *info = &IntUartInfo[minor];
0167 
0168   /* check to see if input is valid */
0169   if (t != (const struct termios *) 0) {
0170     /* determine baud rate index */
0171     baud = rtems_termios_baud_to_number(t->c_ospeed);
0172 
0173     /* determine data bits */
0174     switch (t->c_cflag & CSIZE) {
0175       case CS5:
0176         databits = (int) MCF_UART_UMR_BC_5;
0177         break;
0178       case CS6:
0179         databits = (int) MCF_UART_UMR_BC_6;
0180         break;
0181       case CS7:
0182         databits = (int) MCF_UART_UMR_BC_7;
0183         break;
0184       case CS8:
0185         databits = (int) MCF_UART_UMR_BC_8;
0186         break;
0187     }
0188 
0189     /* determine if parity is enabled */
0190     if (t->c_cflag & PARENB) {
0191       if (t->c_cflag & PARODD) {
0192         /* odd parity */
0193         parity = (int) MCF_UART_UMR_PM_ODD;
0194       } else {
0195         /* even parity */
0196         parity = (int) MCF_UART_UMR_PM_EVEN;
0197       }
0198     }
0199 
0200     /* determine stop bits */
0201     if (t->c_cflag & CSTOPB) {
0202       /* two stop bits */
0203       stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2;
0204     }
0205 
0206     /* check to see if hardware flow control */
0207     if (t->c_cflag & CRTSCTS) {
0208       hwflow = 1;
0209     }
0210   }
0211 
0212   /* check to see if values have changed */
0213   if ((baud != info->baud) ||
0214       (databits != info->databits) ||
0215       (parity != info->parity) ||
0216       (stopbits != info->stopbits) || (hwflow != info->hwflow)) {
0217 
0218     /* call function to set values */
0219     IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
0220   }
0221 
0222   return (RTEMS_SUCCESSFUL);
0223 
0224 }
0225 
0226 /***************************************************************************
0227    Function : IntUartInterruptHandler
0228 
0229    Description : This is the interrupt handler for the internal uart. It
0230    determines which channel caused the interrupt before queueing any received
0231    chars and dequeueing chars waiting for transmission.
0232  ***************************************************************************/
0233 static rtems_isr IntUartInterruptHandler(rtems_vector_number v)
0234 {
0235   unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0);
0236   struct IntUartInfoStruct *info = &IntUartInfo[chan];
0237 
0238   /* check to see if received data */
0239   if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) {
0240     /* read data and put into the receive buffer */
0241     while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) {
0242 
0243       if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) {
0244         /* clear the error */
0245         MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR;
0246       }
0247       /* put data in rx buffer and check for errors */
0248       info->rx_buffer[info->rx_in] = MCF_UART_URB(chan);
0249 
0250       /* update buffer values */
0251       info->rx_in++;
0252 
0253       if (info->rx_in >= RX_BUFFER_SIZE) {
0254         info->rx_in = 0;
0255       }
0256     }
0257     /* Make sure the port has been opened */
0258     if (info->ttyp) {
0259 
0260       /* check to see if task driven */
0261       if (info->iomode == TERMIOS_TASK_DRIVEN) {
0262         /* notify rx task that rx buffer has data */
0263         rtems_termios_rxirq_occured(info->ttyp);
0264       } else {
0265         /* Push up the received data */
0266         rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer,
0267                                              info->rx_in);
0268         info->rx_in = 0;
0269       }
0270     }
0271   }
0272 
0273   /* check to see if data needs to be transmitted */
0274   if ((info->uimr & MCF_UART_UIMR_TXRDY) &&
0275       (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) {
0276 
0277     /* disable tx interrupts */
0278     info->uimr &= ~MCF_UART_UIMR_TXRDY;
0279     MCF_UART_UIMR(chan) = info->uimr;
0280 
0281     /* tell upper level that character has been sent */
0282     if (info->ttyp)
0283       rtems_termios_dequeue_characters(info->ttyp, 1);
0284   }
0285 }
0286 
0287 /***************************************************************************
0288    Function : IntUartInitialize
0289 
0290    Description : This initialises the internal uart hardware for all
0291    internal uarts. If the internal uart is to be interrupt driven then the
0292    interrupt vectors are hooked.
0293  ***************************************************************************/
0294 static void IntUartInitialize(void)
0295 {
0296   unsigned int chan;
0297   struct IntUartInfoStruct *info;
0298   rtems_isr_entry old_handler;
0299   int level;
0300 
0301   for (chan = 0; chan < MAX_UART_INFO; chan++) {
0302     info = &IntUartInfo[chan];
0303 
0304     info->ttyp = NULL;
0305     info->rx_in = 0;
0306     info->rx_out = 0;
0307     info->baud = -1;
0308     info->databits = -1;
0309     info->parity = -1;
0310     info->stopbits = -1;
0311     info->hwflow = -1;
0312     info->iomode = TERMIOS_POLLED;                /*polled console io */
0313 
0314     MCF_UART_UACR(chan) = 0;
0315     MCF_UART_UIMR(chan) = 0;
0316     if (info->iomode != TERMIOS_POLLED) {
0317       rtems_interrupt_catch(IntUartInterruptHandler,
0318                             UART_INTC0_IRQ_VECTOR(chan), &old_handler);
0319     }
0320 
0321     /* set uart default values */
0322     IntUartSetAttributes(chan, NULL);
0323 
0324     /* unmask interrupt */
0325     rtems_interrupt_disable(level);
0326     switch (chan) {
0327       case 0:
0328         MCF_INTC0_ICR26 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL);
0329         MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK26);
0330         break;
0331 
0332       case 1:
0333         MCF_INTC0_ICR27 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL);
0334         MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK27);
0335         break;
0336 
0337       case 2:
0338         MCF_INTC0_ICR28 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL);
0339         MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK28);
0340         break;
0341     }
0342     rtems_interrupt_enable(level);
0343 
0344   }                                               /* of chan loop */
0345 
0346 }                                                 /* IntUartInitialise */
0347 
0348 /***************************************************************************
0349    Function : IntUartInterruptWrite
0350 
0351    Description : This writes a single character to the appropriate uart
0352    channel. This is either called during an interrupt or in the user's task
0353    to initiate a transmit sequence. Calling this routine enables Tx
0354    interrupts.
0355  ***************************************************************************/
0356 static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len)
0357 {
0358   if (len > 0) {
0359     /* write out character */
0360     MCF_UART_UTB(minor) = *buf;
0361 
0362     /* enable tx interrupt */
0363     IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY;
0364     MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr;
0365   }
0366 
0367   return (0);
0368 }
0369 
0370 /***************************************************************************
0371    Function : IntUartInterruptOpen
0372 
0373    Description : This enables interrupts when the tty is opened.
0374  ***************************************************************************/
0375 static int IntUartInterruptOpen(int major, int minor, void *arg)
0376 {
0377   struct IntUartInfoStruct *info = &IntUartInfo[minor];
0378 
0379   /* enable the uart */
0380   MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
0381 
0382   /* check to see if interrupts need to be enabled */
0383   if (info->iomode != TERMIOS_POLLED) {
0384     /* enable rx interrupts */
0385     info->uimr |= MCF_UART_UIMR_RXRDY_FU;
0386     MCF_UART_UIMR(minor) = info->uimr;
0387   }
0388 
0389   /* check to see if doing hardware flow control */
0390   if (info->hwflow) {
0391     /* assert the RTS line */
0392     MCF_UART_UOP1(minor) = 1;
0393   }
0394 
0395   return (0);
0396 }
0397 
0398 /***************************************************************************
0399    Function : IntUartInterruptClose
0400 
0401    Description : This disables interrupts when the tty is closed.
0402  ***************************************************************************/
0403 static int IntUartInterruptClose(int major, int minor, void *arg)
0404 {
0405   struct IntUartInfoStruct *info = &IntUartInfo[minor];
0406 
0407   /* disable the interrupts and the uart */
0408   MCF_UART_UIMR(minor) = 0;
0409   MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
0410 
0411   /* reset values */
0412   info->ttyp = NULL;
0413   info->uimr = 0;
0414   info->rx_in = 0;
0415   info->rx_out = 0;
0416 
0417   return (0);
0418 }
0419 
0420 /***************************************************************************
0421    Function : IntUartTaskRead
0422 
0423    Description : This reads all available characters from the internal uart
0424    and places them into the termios buffer.  The rx interrupts will be
0425    re-enabled after all data has been read.
0426  ***************************************************************************/
0427 static int IntUartTaskRead(int minor)
0428 {
0429   char buffer[RX_BUFFER_SIZE];
0430   int count;
0431   int rx_in;
0432   int index = 0;
0433   struct IntUartInfoStruct *info = &IntUartInfo[minor];
0434 
0435   /* determine number of values to copy out */
0436   rx_in = info->rx_in;
0437   if (info->rx_out <= rx_in) {
0438     count = rx_in - info->rx_out;
0439   } else {
0440     count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
0441   }
0442 
0443   /* copy data into local buffer from rx buffer */
0444   while ((index < count) && (index < RX_BUFFER_SIZE)) {
0445     /* copy data byte */
0446     buffer[index] = info->rx_buffer[info->rx_out];
0447     index++;
0448 
0449     /* increment rx buffer values */
0450     info->rx_out++;
0451     if (info->rx_out >= RX_BUFFER_SIZE) {
0452       info->rx_out = 0;
0453     }
0454   }
0455 
0456   /* check to see if buffer is not empty */
0457   if (count > 0) {
0458     /* set characters into termios buffer  */
0459     rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
0460   }
0461 
0462   return (EOF);
0463 }
0464 
0465 /***************************************************************************
0466    Function : IntUartPollRead
0467 
0468    Description : This reads a character from the internal uart. It returns
0469    to the caller without blocking if not character is waiting.
0470  ***************************************************************************/
0471 static int IntUartPollRead(int minor)
0472 {
0473   if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0)
0474     return (-1);
0475 
0476   return (MCF_UART_URB(minor));
0477 }
0478 
0479 /***************************************************************************
0480    Function : IntUartPollWrite
0481 
0482    Description : This writes out each character in the buffer to the
0483    appropriate internal uart channel waiting till each one is sucessfully
0484    transmitted.
0485  ***************************************************************************/
0486 static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len)
0487 {
0488   size_t retval = len;
0489   /* loop over buffer */
0490   while (len--) {
0491     /* block until we can transmit */
0492     while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0)
0493       continue;
0494     /* transmit data byte */
0495     MCF_UART_UTB(minor) = *buf++;
0496   }
0497   return retval;
0498 }
0499 
0500 /***************************************************************************
0501    Function : console_initialize
0502 
0503    Description : This initialises termios, both sets of uart hardware before
0504    registering /dev/tty devices for each channel and the system /dev/console.
0505  ***************************************************************************/
0506 rtems_device_driver console_initialize(rtems_device_major_number major,
0507                                        rtems_device_minor_number minor,
0508                                        void *arg)
0509 {
0510   rtems_status_code status;
0511 
0512   /* Set up TERMIOS */
0513   rtems_termios_initialize();
0514 
0515   /* set io modes for the different channels and initialize device */
0516   IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN;
0517   IntUartInitialize();
0518 
0519   /* Register the console port */
0520   status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT);
0521   if (status != RTEMS_SUCCESSFUL) {
0522     rtems_fatal_error_occurred(status);
0523   }
0524 
0525   /* Register the other port */
0526   if (CONSOLE_PORT != 0) {
0527     status = rtems_io_register_name("/dev/tty00", major, 0);
0528     if (status != RTEMS_SUCCESSFUL) {
0529       rtems_fatal_error_occurred(status);
0530     }
0531   }
0532   if (CONSOLE_PORT != 1) {
0533     status = rtems_io_register_name("/dev/tty01", major, 1);
0534     if (status != RTEMS_SUCCESSFUL) {
0535       rtems_fatal_error_occurred(status);
0536     }
0537   }
0538 
0539   return (RTEMS_SUCCESSFUL);
0540 }
0541 
0542 /***************************************************************************
0543    Function : console_open
0544 
0545    Description : This actually opens the device depending on the minor
0546    number set during initialisation. The device specific access routines are
0547    passed to termios when the devices is opened depending on whether it is
0548    polled or not.
0549  ***************************************************************************/
0550 rtems_device_driver console_open(rtems_device_major_number major,
0551                                  rtems_device_minor_number minor, void *arg)
0552 {
0553   rtems_status_code status = RTEMS_INVALID_NUMBER;
0554   rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg;
0555   struct IntUartInfoStruct *info;
0556 
0557   static const rtems_termios_callbacks IntUartPollCallbacks = {
0558     NULL,                                         /* firstOpen */
0559     NULL,                                         /* lastClose */
0560     IntUartPollRead,                              /* pollRead */
0561     IntUartPollWrite,                             /* write */
0562     IntUartSetAttributes,                         /* setAttributes */
0563     NULL,                                         /* stopRemoteTx */
0564     NULL,                                         /* startRemoteTx */
0565     TERMIOS_POLLED                                /* mode */
0566   };
0567   static const rtems_termios_callbacks IntUartIntrCallbacks = {
0568     IntUartInterruptOpen,                         /* firstOpen */
0569     IntUartInterruptClose,                        /* lastClose */
0570     NULL,                                         /* pollRead */
0571     IntUartInterruptWrite,                        /* write */
0572     IntUartSetAttributes,                         /* setAttributes */
0573     NULL,                                         /* stopRemoteTx */
0574     NULL,                                         /* startRemoteTx */
0575     TERMIOS_IRQ_DRIVEN                            /* mode */
0576   };
0577 
0578   static const rtems_termios_callbacks IntUartTaskCallbacks = {
0579     IntUartInterruptOpen,                         /* firstOpen */
0580     IntUartInterruptClose,                        /* lastClose */
0581     IntUartTaskRead,                              /* pollRead */
0582     IntUartInterruptWrite,                        /* write */
0583     IntUartSetAttributes,                         /* setAttributes */
0584     NULL,                                         /* stopRemoteTx */
0585     NULL,                                         /* startRemoteTx */
0586     TERMIOS_TASK_DRIVEN                           /* mode */
0587   };
0588 
0589   /* open the port depending on the minor device number */
0590   if ((minor >= 0) && (minor < MAX_UART_INFO)) {
0591     info = &IntUartInfo[minor];
0592     switch (info->iomode) {
0593       case TERMIOS_POLLED:
0594         status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
0595         break;
0596       case TERMIOS_IRQ_DRIVEN:
0597         status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
0598         info->ttyp = args->iop->data1;
0599         break;
0600       case TERMIOS_TASK_DRIVEN:
0601         status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
0602         info->ttyp = args->iop->data1;
0603         break;
0604     }
0605   }
0606 
0607   if (status == RTEMS_SUCCESSFUL) {
0608     /*
0609      * Reset the default baudrate.
0610      */
0611     struct termios term;
0612 
0613     if (tcgetattr(STDIN_FILENO, &term) >= 0) {
0614       term.c_cflag &= ~(CSIZE);
0615       term.c_cflag |= CS8;
0616       term.c_ispeed = B19200;
0617       term.c_ospeed = B19200;
0618       tcsetattr(STDIN_FILENO, TCSANOW, &term);
0619     }
0620   }
0621 
0622   return (status);
0623 }
0624 
0625 /***************************************************************************
0626    Function : console_close
0627 
0628    Description : This closes the device via termios
0629  ***************************************************************************/
0630 rtems_device_driver console_close(rtems_device_major_number major,
0631                                   rtems_device_minor_number minor, void *arg)
0632 {
0633   return (rtems_termios_close(arg));
0634 }
0635 
0636 /***************************************************************************
0637    Function : console_read
0638 
0639    Description : Read from the device via termios
0640  ***************************************************************************/
0641 rtems_device_driver console_read(rtems_device_major_number major,
0642                                  rtems_device_minor_number minor, void *arg)
0643 {
0644   return (rtems_termios_read(arg));
0645 }
0646 
0647 /***************************************************************************
0648    Function : console_write
0649 
0650    Description : Write to the device via termios
0651  ***************************************************************************/
0652 rtems_device_driver console_write(rtems_device_major_number major,
0653                                   rtems_device_minor_number minor, void *arg)
0654 {
0655   return (rtems_termios_write(arg));
0656 }
0657 
0658 /***************************************************************************
0659    Function : console_ioctl
0660 
0661    Description : Pass the IOCtl call to termios
0662  ***************************************************************************/
0663 rtems_device_driver console_control(rtems_device_major_number major,
0664                                     rtems_device_minor_number minor,
0665                                     void *arg)
0666 {
0667   return (rtems_termios_ioctl(arg));
0668 }