Back to home page

LXR

 
 

    


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

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