source: rtems/bsps/m68k/mcf52235/console/console.c @ d7d66d7

5
Last change on this file since d7d66d7 was d7d66d7, checked in by Sebastian Huber <sebastian.huber@…>, on 04/19/18 at 04:28:01

bsps: Move console drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 20.5 KB
RevLine 
[3aac2db]1 /*
2  *  Multi UART console serial I/O.
3  *
4  * TO DO: Add DMA input/output
5  */
6
7#include <stdio.h>
8#include <fcntl.h>
9#include <termios.h>
10#include <malloc.h>
[878d634]11
12#include <rtems/libio.h>
13#include <rtems/console.h>
14#include <rtems/termiostypes.h>
15#include <bsp.h>
[3aac2db]16
17#include <rtems/bspIo.h>
18
19#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x))
20
21#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \
22                             MCF_UART_USR_FE | \
23                             MCF_UART_USR_PE | \
24                             MCF_UART_USR_OE )
25
[39a9f8e]26static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
27static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len);
[3aac2db]28
29#define MAX_UART_INFO     3
30#define RX_BUFFER_SIZE    512
31
32struct IntUartInfoStruct
33{
[9374e9b0]34  int iomode;
35  volatile int uimr;
36  int baud;
37  int databits;
38  int parity;
39  int stopbits;
40  int hwflow;
41  int rx_in;
42  int rx_out;
43  char rx_buffer[RX_BUFFER_SIZE];
44  void *ttyp;
[3aac2db]45};
46
47struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
48
49/***************************************************************************
50   Function : IntUartSet
51
52   Description : This updates the hardware UART settings.
53 ***************************************************************************/
54static void
[9374e9b0]55IntUartSet(int minor, int baud, int databits, int parity, int stopbits,
56           int hwflow)
[3aac2db]57{
[9374e9b0]58  int divisor;
59  uint32_t clock_speed;
60  uint8_t umr1 = 0;
61  uint8_t umr2 = 0;
62  struct IntUartInfoStruct *info = &IntUartInfo[minor];
63  int level;
64
65  rtems_interrupt_disable(level);
66
67  /* disable interrupts, clear RTS line, and disable the UARTS */
68  MCF_UART_UIMR(minor) = 0;
69  MCF_UART_UOP0(minor) = 1;
70  MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
71
72  /* save the current values */
73  info->uimr = 0;
74  info->baud = baud;
75  info->databits = databits;
76  info->parity = parity;
77  info->stopbits = stopbits;
78  info->hwflow = hwflow;
79
80  clock_speed = bsp_get_CPU_clock_speed();
81  /* determine the baud divisor value */
82  divisor = ((clock_speed) / (32 * baud));
83  if (divisor < 2)
84    divisor = 2;
85
86  /* check to see if doing hardware flow control */
87  if (hwflow) {
88    /* set hardware flow options */
89    umr1 |= MCF_UART_UMR_RXRTS;
90    umr2 |= MCF_UART_UMR_TXCTS;
91  }
92
93  /* determine the new umr values */
94  umr1 |= (parity | databits);
95  umr2 |= (stopbits);
96
97  /* reset the uart */
98  MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR;
99  MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX;
100  MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX;
101
102  /* reset the uart mode register and update values */
103  MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR;
104  MCF_UART_UMR(minor) = umr1;
105  MCF_UART_UMR(minor) = umr2;
106
107  /* set the baud rate values */
108  MCF_UART_UCSR(minor) =
109    (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK);
110  MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
111  MCF_UART_UBG2(minor) = (divisor & 0x00ff);
112
113  /* enable the uart */
114  MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
115
116  /* check to see if interrupts need to be enabled */
117  if (info->iomode != TERMIOS_POLLED) {
118    /* enable rx interrupts */
119    info->uimr |= MCF_UART_UIMR_RXRDY_FU;
120    MCF_UART_UIMR(minor) = info->uimr;
121  }
122
123  /* check to see if doing hardware flow control */
124  if (hwflow) {
125    /* assert the RTS line */
126    MCF_UART_UOP1(minor) = 1;
127  }
128
129  rtems_interrupt_enable(level);
[3aac2db]130
131}
132
133/***************************************************************************
134   Function : IntUartSetAttributes
135
136   Description : This provides the hardware-dependent portion of tcsetattr().
137   value and sets it. At the moment this just sets the baud rate.
138
[d4b4664b]139   Note: The highest baudrate is 115200 as this stays within
[3aac2db]140   an error of +/- 5% at 25MHz processor clock
141 ***************************************************************************/
[9374e9b0]142static int IntUartSetAttributes(int minor, const struct termios *t)
[3aac2db]143{
[9374e9b0]144  /* set default index values */
145  int baud = (int) 19200;
146  int databits = (int) MCF_UART_UMR_BC_8;
147  int parity = (int) MCF_UART_UMR_PM_NONE;
148  int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1;
149  int hwflow = (int) 0;
150  struct IntUartInfoStruct *info = &IntUartInfo[minor];
151
152  /* check to see if input is valid */
153  if (t != (const struct termios *) 0) {
154    /* determine baud rate index */
[1c6926c1]155    baud = rtems_termios_baud_to_number(t->c_ospeed);
[9374e9b0]156
157    /* determine data bits */
158    switch (t->c_cflag & CSIZE) {
159      case CS5:
160        databits = (int) MCF_UART_UMR_BC_5;
161        break;
162      case CS6:
163        databits = (int) MCF_UART_UMR_BC_6;
164        break;
165      case CS7:
166        databits = (int) MCF_UART_UMR_BC_7;
167        break;
168      case CS8:
169        databits = (int) MCF_UART_UMR_BC_8;
170        break;
171    }
172
173    /* determine if parity is enabled */
174    if (t->c_cflag & PARENB) {
175      if (t->c_cflag & PARODD) {
176        /* odd parity */
177        parity = (int) MCF_UART_UMR_PM_ODD;
178      } else {
179        /* even parity */
180        parity = (int) MCF_UART_UMR_PM_EVEN;
181      }
182    }
183
184    /* determine stop bits */
185    if (t->c_cflag & CSTOPB) {
186      /* two stop bits */
187      stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2;
188    }
189
190    /* check to see if hardware flow control */
191    if (t->c_cflag & CRTSCTS) {
192      hwflow = 1;
193    }
194  }
195
196  /* check to see if values have changed */
197  if ((baud != info->baud) ||
198      (databits != info->databits) ||
199      (parity != info->parity) ||
200      (stopbits != info->stopbits) || (hwflow != info->hwflow)) {
201
202    /* call function to set values */
203    IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
204  }
205
206  return (RTEMS_SUCCESSFUL);
[3aac2db]207
208}
209
210/***************************************************************************
211   Function : IntUartInterruptHandler
212
213   Description : This is the interrupt handler for the internal uart. It
214   determines which channel caused the interrupt before queueing any received
215   chars and dequeueing chars waiting for transmission.
216 ***************************************************************************/
[9374e9b0]217static rtems_isr IntUartInterruptHandler(rtems_vector_number v)
[3aac2db]218{
[9374e9b0]219  unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0);
220  struct IntUartInfoStruct *info = &IntUartInfo[chan];
221
222  /* check to see if received data */
223  if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) {
224    /* read data and put into the receive buffer */
225    while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) {
226
227      if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) {
228        /* clear the error */
229        MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR;
230      }
231      /* put data in rx buffer and check for errors */
232      info->rx_buffer[info->rx_in] = MCF_UART_URB(chan);
233
234      /* update buffer values */
235      info->rx_in++;
236
237      if (info->rx_in >= RX_BUFFER_SIZE) {
238        info->rx_in = 0;
239      }
240    }
241    /* Make sure the port has been opened */
242    if (info->ttyp) {
243
244      /* check to see if task driven */
245      if (info->iomode == TERMIOS_TASK_DRIVEN) {
246        /* notify rx task that rx buffer has data */
247        rtems_termios_rxirq_occured(info->ttyp);
248      } else {
249        /* Push up the received data */
250        rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer,
251                                             info->rx_in);
252        info->rx_in = 0;
253      }
254    }
255  }
256
257  /* check to see if data needs to be transmitted */
258  if ((info->uimr & MCF_UART_UIMR_TXRDY) &&
259      (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) {
260
261    /* disable tx interrupts */
262    info->uimr &= ~MCF_UART_UIMR_TXRDY;
263    MCF_UART_UIMR(chan) = info->uimr;
264
265    /* tell upper level that character has been sent */
266    if (info->ttyp)
267      rtems_termios_dequeue_characters(info->ttyp, 1);
268  }
[3aac2db]269}
270
271/***************************************************************************
272   Function : IntUartInitialize
273
274   Description : This initialises the internal uart hardware for all
275   internal uarts. If the internal uart is to be interrupt driven then the
276   interrupt vectors are hooked.
277 ***************************************************************************/
[9374e9b0]278static void IntUartInitialize(void)
[3aac2db]279{
[9374e9b0]280  unsigned int chan;
281  struct IntUartInfoStruct *info;
282  rtems_isr_entry old_handler;
283  int level;
284
285  for (chan = 0; chan < MAX_UART_INFO; chan++) {
286    info = &IntUartInfo[chan];
287
288    info->ttyp = NULL;
289    info->rx_in = 0;
290    info->rx_out = 0;
291    info->baud = -1;
292    info->databits = -1;
293    info->parity = -1;
294    info->stopbits = -1;
295    info->hwflow = -1;
296    info->iomode = TERMIOS_POLLED;                /*polled console io */
297
298    MCF_UART_UACR(chan) = 0;
299    MCF_UART_UIMR(chan) = 0;
300    if (info->iomode != TERMIOS_POLLED) {
301      rtems_interrupt_catch(IntUartInterruptHandler,
302                            UART_INTC0_IRQ_VECTOR(chan), &old_handler);
303    }
304
305    /* set uart default values */
306    IntUartSetAttributes(chan, NULL);
307
308    /* unmask interrupt */
309    rtems_interrupt_disable(level);
310    switch (chan) {
311      case 0:
312        MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) |
313          MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY);
314        MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL);
315        break;
316
317      case 1:
318        MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) |
319          MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY);
320        MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL);
321        break;
322
323      case 2:
324        MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) |
325          MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY);
326        MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL);
327        break;
328    }
329    rtems_interrupt_enable(level);
330
331  }                                               /* of chan loop */
332
333}                                                 /* IntUartInitialise */
[3aac2db]334
335/***************************************************************************
336   Function : IntUartInterruptWrite
337
[d4b4664b]338   Description : This writes a single character to the appropriate uart
[3aac2db]339   channel. This is either called during an interrupt or in the user's task
[d4b4664b]340   to initiate a transmit sequence. Calling this routine enables Tx
[3aac2db]341   interrupts.
342 ***************************************************************************/
[39a9f8e]343static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len)
[3aac2db]344{
[e18db9f]345  if (len > 0) {
346    /* write out character */
347    MCF_UART_UTB(minor) = *buf;
[3aac2db]348
[e18db9f]349    /* enable tx interrupt */
350    IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY;
351    MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr;
352  }
[3aac2db]353
[9374e9b0]354  return (0);
[3aac2db]355}
356
357/***************************************************************************
358   Function : IntUartInterruptOpen
359
360   Description : This enables interrupts when the tty is opened.
361 ***************************************************************************/
[9374e9b0]362static int IntUartInterruptOpen(int major, int minor, void *arg)
[3aac2db]363{
[9374e9b0]364  struct IntUartInfoStruct *info = &IntUartInfo[minor];
[3aac2db]365
[9374e9b0]366  /* enable the uart */
367  MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
[3aac2db]368
[9374e9b0]369  /* check to see if interrupts need to be enabled */
370  if (info->iomode != TERMIOS_POLLED) {
371    /* enable rx interrupts */
372    info->uimr |= MCF_UART_UIMR_RXRDY_FU;
373    MCF_UART_UIMR(minor) = info->uimr;
374  }
375
376  /* check to see if doing hardware flow control */
377  if (info->hwflow) {
378    /* assert the RTS line */
379    MCF_UART_UOP1(minor) = 1;
380  }
381
382  return (0);
383}
[3aac2db]384
385/***************************************************************************
386   Function : IntUartInterruptClose
387
388   Description : This disables interrupts when the tty is closed.
389 ***************************************************************************/
[9374e9b0]390static int IntUartInterruptClose(int major, int minor, void *arg)
[3aac2db]391{
[9374e9b0]392  struct IntUartInfoStruct *info = &IntUartInfo[minor];
[3aac2db]393
[9374e9b0]394  /* disable the interrupts and the uart */
395  MCF_UART_UIMR(minor) = 0;
396  MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
[3aac2db]397
[9374e9b0]398  /* reset values */
399  info->ttyp = NULL;
400  info->uimr = 0;
401  info->rx_in = 0;
402  info->rx_out = 0;
[3aac2db]403
[9374e9b0]404  return (0);
[3aac2db]405}
406
407/***************************************************************************
408   Function : IntUartTaskRead
409
410   Description : This reads all available characters from the internal uart
411   and places them into the termios buffer.  The rx interrupts will be
412   re-enabled after all data has been read.
413 ***************************************************************************/
[9374e9b0]414static int IntUartTaskRead(int minor)
[3aac2db]415{
[9374e9b0]416  char buffer[RX_BUFFER_SIZE];
417  int count;
418  int rx_in;
419  int index = 0;
420  struct IntUartInfoStruct *info = &IntUartInfo[minor];
421
422  /* determine number of values to copy out */
423  rx_in = info->rx_in;
424  if (info->rx_out <= rx_in) {
425    count = rx_in - info->rx_out;
426  } else {
427    count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
428  }
429
430  /* copy data into local buffer from rx buffer */
431  while ((index < count) && (index < RX_BUFFER_SIZE)) {
432    /* copy data byte */
433    buffer[index] = info->rx_buffer[info->rx_out];
434    index++;
435
436    /* increment rx buffer values */
437    info->rx_out++;
438    if (info->rx_out >= RX_BUFFER_SIZE) {
439      info->rx_out = 0;
440    }
441  }
442
443  /* check to see if buffer is not empty */
444  if (count > 0) {
445    /* set characters into termios buffer  */
446    rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
447  }
448
449  return (EOF);
[3aac2db]450}
451
452/***************************************************************************
453   Function : IntUartPollRead
454
[d4b4664b]455   Description : This reads a character from the internal uart. It returns
[3aac2db]456   to the caller without blocking if not character is waiting.
457 ***************************************************************************/
[9374e9b0]458static int IntUartPollRead(int minor)
[3aac2db]459{
[9374e9b0]460  if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0)
461    return (-1);
[3aac2db]462
[9374e9b0]463  return (MCF_UART_URB(minor));
[3aac2db]464}
465
466/***************************************************************************
467   Function : IntUartPollWrite
468
[d4b4664b]469   Description : This writes out each character in the buffer to the
470   appropriate internal uart channel waiting till each one is sucessfully
[3aac2db]471   transmitted.
472 ***************************************************************************/
[39a9f8e]473static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len)
[3aac2db]474{
[39a9f8e]475  size_t retval = len;
[9374e9b0]476  /* loop over buffer */
477  while (len--) {
478    /* block until we can transmit */
479    while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0)
480      continue;
481    /* transmit data byte */
482    MCF_UART_UTB(minor) = *buf++;
483  }
[39a9f8e]484  return retval;
[3aac2db]485}
486
487/***************************************************************************
488   Function : console_initialize
489
490   Description : This initialises termios, both sets of uart hardware before
491   registering /dev/tty devices for each channel and the system /dev/console.
492 ***************************************************************************/
[9374e9b0]493rtems_device_driver console_initialize(rtems_device_major_number major,
494                                       rtems_device_minor_number minor,
495                                       void *arg)
[3aac2db]496{
[9374e9b0]497  rtems_status_code status;
498
499  /* Set up TERMIOS */
500  rtems_termios_initialize();
501
502  /* set io modes for the different channels and initialize device */
503  IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN;
504  IntUartInitialize();
505
506  /* Register the console port */
507  status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT);
508  if (status != RTEMS_SUCCESSFUL) {
509    rtems_fatal_error_occurred(status);
510  }
511
512  /* Register the other port */
513  if (CONSOLE_PORT != 0) {
514    status = rtems_io_register_name("/dev/tty00", major, 0);
515    if (status != RTEMS_SUCCESSFUL) {
516      rtems_fatal_error_occurred(status);
517    }
518  }
519  if (CONSOLE_PORT != 1) {
520    status = rtems_io_register_name("/dev/tty01", major, 1);
521    if (status != RTEMS_SUCCESSFUL) {
522      rtems_fatal_error_occurred(status);
523    }
524  }
525
526  return (RTEMS_SUCCESSFUL);
[3aac2db]527}
528
529/***************************************************************************
530   Function : console_open
531
[d4b4664b]532   Description : This actually opens the device depending on the minor
[3aac2db]533   number set during initialisation. The device specific access routines are
534   passed to termios when the devices is opened depending on whether it is
535   polled or not.
536 ***************************************************************************/
[9374e9b0]537rtems_device_driver console_open(rtems_device_major_number major,
538                                 rtems_device_minor_number minor, void *arg)
[3aac2db]539{
[9374e9b0]540  rtems_status_code status = RTEMS_INVALID_NUMBER;
541  rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg;
542  struct IntUartInfoStruct *info;
543
544  static const rtems_termios_callbacks IntUartPollCallbacks = {
545    NULL,                                         /* firstOpen */
546    NULL,                                         /* lastClose */
547    IntUartPollRead,                              /* pollRead */
548    IntUartPollWrite,                             /* write */
549    IntUartSetAttributes,                         /* setAttributes */
550    NULL,                                         /* stopRemoteTx */
551    NULL,                                         /* startRemoteTx */
552    TERMIOS_POLLED                                /* mode */
553  };
554  static const rtems_termios_callbacks IntUartIntrCallbacks = {
555    IntUartInterruptOpen,                         /* firstOpen */
556    IntUartInterruptClose,                        /* lastClose */
557    NULL,                                         /* pollRead */
558    IntUartInterruptWrite,                        /* write */
559    IntUartSetAttributes,                         /* setAttributes */
560    NULL,                                         /* stopRemoteTx */
561    NULL,                                         /* startRemoteTx */
562    TERMIOS_IRQ_DRIVEN                            /* mode */
563  };
564
565  static const rtems_termios_callbacks IntUartTaskCallbacks = {
566    IntUartInterruptOpen,                         /* firstOpen */
567    IntUartInterruptClose,                        /* lastClose */
568    IntUartTaskRead,                              /* pollRead */
569    IntUartInterruptWrite,                        /* write */
570    IntUartSetAttributes,                         /* setAttributes */
571    NULL,                                         /* stopRemoteTx */
572    NULL,                                         /* startRemoteTx */
573    TERMIOS_TASK_DRIVEN                           /* mode */
574  };
575
576  /* open the port depending on the minor device number */
577  if ((minor >= 0) && (minor < MAX_UART_INFO)) {
578    info = &IntUartInfo[minor];
579    switch (info->iomode) {
580      case TERMIOS_POLLED:
581        status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
582        break;
583      case TERMIOS_IRQ_DRIVEN:
584        status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
585        info->ttyp = args->iop->data1;
586        break;
587      case TERMIOS_TASK_DRIVEN:
588        status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
589        info->ttyp = args->iop->data1;
590        break;
591    }
592  }
593
594  if (status == RTEMS_SUCCESSFUL) {
595    /*
596     * Reset the default baudrate.
597     */
598    struct termios term;
599
600    if (tcgetattr(STDIN_FILENO, &term) >= 0) {
[1c6926c1]601      term.c_cflag &= ~(CSIZE);
602      term.c_cflag |= CS8;
603      term.c_ispeed = B19200;
604      term.c_ospeed = B19200;
[9374e9b0]605      tcsetattr(STDIN_FILENO, TCSANOW, &term);
606    }
607  }
608
609  return (status);
[3aac2db]610}
611
612/***************************************************************************
613   Function : console_close
614
615   Description : This closes the device via termios
616 ***************************************************************************/
[9374e9b0]617rtems_device_driver console_close(rtems_device_major_number major,
618                                  rtems_device_minor_number minor, void *arg)
[3aac2db]619{
[9374e9b0]620  return (rtems_termios_close(arg));
[3aac2db]621}
622
623/******************
624*********************************************************
625   Function : console_read
626
627   Description : Read from the device via termios
628 ***************************************************************************/
[9374e9b0]629rtems_device_driver console_read(rtems_device_major_number major,
630                                 rtems_device_minor_number minor, void *arg)
[3aac2db]631{
[9374e9b0]632  return (rtems_termios_read(arg));
[3aac2db]633}
634
635/***************************************************************************
636   Function : console_write
637
638   Description : Write to the device via termios
639 ***************************************************************************/
[9374e9b0]640rtems_device_driver console_write(rtems_device_major_number major,
641                                  rtems_device_minor_number minor, void *arg)
[3aac2db]642{
[9374e9b0]643  return (rtems_termios_write(arg));
[3aac2db]644}
645
646/***************************************************************************
647   Function : console_ioctl
648
649   Description : Pass the IOCtl call to termios
650 ***************************************************************************/
[9374e9b0]651rtems_device_driver console_control(rtems_device_major_number major,
652                                    rtems_device_minor_number minor,
653                                    void *arg)
[3aac2db]654{
[9374e9b0]655  return (rtems_termios_ioctl(arg));
[3aac2db]656}
Note: See TracBrowser for help on using the repository browser.