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