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

Last change on this file since 66093623 was 66093623, checked in by Joel Sherrill <joel@…>, on Mar 29, 2016 at 7:05:34 PM

m68k/mcf5225x/console/console.c: Remove unneeded include of <rtems/mw_uid.h>

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