source: rtems/c/src/lib/libbsp/m68k/mcf5225x/console/console.c @ a6e7c575

5
Last change on this file since a6e7c575 was cdf41c1a, checked in by Joel Sherrill <joel@…>, on 03/29/16 at 18:10:51

m68k/mcf5225x: Remove include of <rtems/console.h> from <bsp.h> and fix warnings

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