source: rtems/c/src/lib/libbsp/i386/shared/comm/tty_drv.c @ 1c6926c1

Last change on this file since 1c6926c1 was 1c6926c1, checked in by Kevin Kirspel <kevin-kirspel@…>, on Mar 21, 2017 at 7:39:48 PM

termios: Synchronize with latest FreeBSD headers

Adding modified FreeBSD headers to synchronize RTEMS termios with
FreeBSD. Modify termios to support dedicated input and output baud for
termios structure. Updated BSPs to use dedicated input and output baud
in termios structure. Updated tools to use dedicated input and output
baud in termios structure. Updated termios testsuites to use dedicated
input and output baud in termios structure.

Close #2897.

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/***************************************************************************
2 *
3 * MODULE DESCRIPTION:
4 * This module implements the RTEMS drivers for the PC serial ports
5 * as /dev/ttyS1 for COM1 and /dev/ttyS2 as COM2. If one of the ports
6 * is used as the console, this driver would fail to initialize.
7 *
8 * This code was based on the console driver. It is based on the
9 * current termios framework. This is just a shell around the
10 * termios support.
11 *
12 * by: Rosimildo da Silva:
13 *     rdasilva@connecttel.com
14 *     http://www.connecttel.com
15 *
16 ****************************************************************************/
17
18
19#include <inttypes.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <assert.h>
23
24#include <bsp.h>
25#include <bsp/irq.h>
26#include <rtems/bspIo.h>
27#include <rtems/libio.h>
28#include <rtems/termiostypes.h>
29#include <termios.h>
30#include <uart.h>
31#include <libcpu/cpuModel.h>
32#include "tty_drv.h"
33
34int BSP_poll_read(int);
35
36/* Internal routines */
37static int tty1_conSetAttr( int minor, const struct termios *t);
38static int tty2_conSetAttr( int minor, const struct termios *t);
39
40extern BSP_polling_getchar_function_type BSP_poll_char;
41extern int BSPConsolePort;
42extern void rtems_set_waiting_id_comx( int port,  rtems_id id, rtems_event_set event );
43
44/*
45 *  TTYS1 - device driver INITIALIZE entry point.
46 */
47rtems_device_driver
48tty1_initialize(rtems_device_major_number major,
49                   rtems_device_minor_number minor,
50                   void                      *arg)
51{
52  rtems_status_code status;
53
54  /* Check if this port is not been used as console */
55  if( BSPConsolePort == BSP_UART_COM1 )
56  {
57    status = -1;
58    printk("TTYS1: port selected as console.\n");
59    rtems_fatal_error_occurred( status );
60  }
61
62  /*
63   * Set up TERMIOS
64   */
65  rtems_termios_initialize();
66
67  /*
68   * Do device-specific initialization
69   */
70  /* 9600-8-N-1, without hardware flow control */
71  BSP_uart_init( BSP_UART_COM1, 9600, CHR_8_BITS, 0, 0, 0 );
72  status = rtems_interrupt_handler_install(
73    BSP_UART_COM1_IRQ,
74    "tty_drv",
75    RTEMS_INTERRUPT_UNIQUE,
76    BSP_uart_termios_isr_com1,
77    NULL
78  );
79  assert(status == RTEMS_SUCCESSFUL);
80  /*
81   * Register the device
82   */
83  status = rtems_io_register_name ("/dev/ttyS1", major, 0);
84  if (status != RTEMS_SUCCESSFUL)
85  {
86      printk("Error registering ttyS1 device!\n");
87      rtems_fatal_error_occurred (status);
88  }
89  printk("Device: /dev/ttyS1 initialized.\n");
90  return RTEMS_SUCCESSFUL;
91} /* tty_initialize */
92
93static int tty1_last_close(int major, int minor, void *arg)
94{
95  rtems_status_code status;
96
97  status = rtems_interrupt_handler_remove(
98    BSP_UART_COM1_IRQ,
99    BSP_uart_termios_isr_com1,
100    NULL
101  );
102  assert(status == RTEMS_SUCCESSFUL);
103  return 0;
104}
105
106/*
107 * TTY1 - device driver OPEN entry point
108 */
109rtems_device_driver
110tty1_open(rtems_device_major_number major,
111                rtems_device_minor_number minor,
112                void                      *arg)
113{
114  rtems_status_code  status;
115#ifndef USE_TASK_DRIVEN
116  static rtems_termios_callbacks cb =
117  {
118    NULL,                        /* firstOpen */
119    tty1_last_close,             /* lastClose */
120    NULL,                        /* poll read */
121    BSP_uart_termios_write_com1, /* write */
122    tty1_conSetAttr,             /* setAttributes */
123    NULL,                        /* stopRemoteTx */
124    NULL,                        /* startRemoteTx */
125    TERMIOS_IRQ_DRIVEN           /* outputUsesInterrupts */
126  };
127#else
128  static rtems_termios_callbacks cb =
129  {
130    NULL,                        /* firstOpen */
131    NULL,                        /* lastClose */
132    BSP_uart_termios_read_com1,  /* poll read */
133    BSP_uart_termios_write_com1, /* write */
134    tty1_conSetAttr,             /* setAttributes */
135    NULL,                        /* stopRemoteTx */
136    NULL,                        /* startRemoteTx */
137    TERMIOS_TASK_DRIVEN          /* outputUsesInterrupts */
138  };
139#endif
140
141  status = rtems_termios_open( major, minor, arg, &cb );
142  if(status != RTEMS_SUCCESSFUL)
143  {
144     printk("Error openning tty1 device\n");
145     return status;
146  }
147
148  /*
149   * Pass data area info down to driver
150   */
151  BSP_uart_termios_set( BSP_UART_COM1,
152                       ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
153  /* Enable interrupts  on channel */
154  BSP_uart_intr_ctrl( BSP_UART_COM1, BSP_UART_INTR_CTRL_TERMIOS);
155  return RTEMS_SUCCESSFUL;
156}
157
158/*
159 * TTY - device driver CLOSE entry point
160 */
161rtems_device_driver
162tty_close(rtems_device_major_number major,
163              rtems_device_minor_number minor,
164              void                      *arg)
165{
166
167  return (rtems_termios_close (arg));
168
169} /* tty_close */
170
171/*
172 * TTY device driver READ entry point.
173 * Read characters from the tty device.
174 */
175rtems_device_driver
176tty_read(rtems_device_major_number major,
177             rtems_device_minor_number minor,
178             void                      *arg)
179{
180  return rtems_termios_read (arg);
181} /* tty_read */
182
183/*
184 * TTY device driver WRITE entry point.
185 * Write characters to the tty device.
186 */
187rtems_device_driver
188tty_write(rtems_device_major_number major,
189              rtems_device_minor_number minor,
190              void                    * arg)
191{
192    return rtems_termios_write (arg);
193
194} /* tty_write */
195
196/*
197 * Handle ioctl request. This is a generic internal
198 * routine to handle both devices.
199 */
200static rtems_device_driver tty_control( int port, void  *arg )
201{
202        rtems_libio_ioctl_args_t *args = arg;
203        switch( args->command )
204        {
205           default:
206      return rtems_termios_ioctl (arg);
207                break;
208   }
209        args->ioctl_return = 0;
210   return RTEMS_SUCCESSFUL;
211}
212
213/*
214 * Handle ioctl request for ttyS1.
215 */
216rtems_device_driver
217tty1_control(rtems_device_major_number major,
218                rtems_device_minor_number minor,
219                void                      * arg
220)
221{
222  return tty_control( BSP_UART_COM1, arg );
223}
224
225static int
226conSetAttr(int port, int minor, const struct termios *t)
227{
228  unsigned long baud, databits, parity, stopbits;
229
230  baud = rtems_termios_baud_to_number(t->c_ospeed);
231  if ( baud > 115200 )
232    rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
233
234  if (t->c_cflag & PARENB) {
235    /* Parity is enabled */
236    if (t->c_cflag & PARODD) {
237      /* Parity is odd */
238      parity = PEN;
239    }
240    else {
241      /* Parity is even */
242      parity = PEN | EPS;
243    }
244  }
245  else {
246    /* No parity */
247    parity = 0;
248  }
249
250  switch (t->c_cflag & CSIZE) {
251    case CS5: databits = CHR_5_BITS; break;
252    case CS6: databits = CHR_6_BITS; break;
253    case CS7: databits = CHR_7_BITS; break;
254    default:  /* just to avoid warnings -- all cases are covered */
255    case CS8: databits = CHR_8_BITS; break;
256  }
257
258  if (t->c_cflag & CSTOPB) {
259    /* 2 stop bits */
260    stopbits = STB;
261  }
262  else {
263    /* 1 stop bit */
264    stopbits = 0;
265  }
266
267  printk("Setting attributes, port=%X, baud=%" PRId32 ", linemode = 0x%02" PRIx32 "\n",
268         port, baud, databits | parity | stopbits );
269  BSP_uart_set_attributes(port, baud, databits, parity, stopbits);
270  return 0;
271}
272
273/*
274 * Handle ioctl request for ttyS2.
275 */
276static int
277tty1_conSetAttr( int minor, const struct termios *t)
278{
279  return conSetAttr( BSP_UART_COM1, minor, t );
280}
281
282/*
283 * TTY2 device driver INITIALIZE entry point.
284 */
285rtems_device_driver
286tty2_initialize(rtems_device_major_number major,
287                   rtems_device_minor_number minor,
288                   void                      *arg)
289{
290  rtems_status_code status;
291
292  /* Check if this port is not been used as console */
293  if( BSPConsolePort == BSP_UART_COM2 )
294  {
295    status = -1;
296    printk("TTY2: port selected as console.\n");
297    rtems_fatal_error_occurred( status );
298  }
299
300  /*
301   * Set up TERMIOS
302   */
303  rtems_termios_initialize();
304
305  /*
306   * Do device-specific initialization
307   */
308  /* 9600-8-N-1, without hardware flow control */
309  BSP_uart_init( BSP_UART_COM2, 9600, CHR_8_BITS, 0, 0, 0);
310  status = rtems_interrupt_handler_install(
311    BSP_UART_COM2_IRQ,
312    "tty_drv",
313    RTEMS_INTERRUPT_UNIQUE,
314    BSP_uart_termios_isr_com2,
315    NULL
316  );
317  assert(status == RTEMS_SUCCESSFUL);
318
319  /*
320   * Register the device
321   */
322  status = rtems_io_register_name ("/dev/ttyS2", major, 0);
323  if (status != RTEMS_SUCCESSFUL)
324  {
325      printk("Error registering tty2 device!\n");
326      rtems_fatal_error_occurred (status);
327  }
328  printk("Device: /dev/ttyS2 initialized.\n");
329  return RTEMS_SUCCESSFUL;
330} /* tty_initialize */
331
332static int tty2_last_close(int major, int minor, void *arg)
333{
334  rtems_status_code status;
335
336  status = rtems_interrupt_handler_remove(
337    BSP_UART_COM2_IRQ,
338    BSP_uart_termios_isr_com2,
339    NULL
340  );
341  assert(status == RTEMS_SUCCESSFUL);
342  return 0;
343}
344
345/*
346 * TTY2 device driver OPEN entry point
347 */
348rtems_device_driver
349tty2_open(rtems_device_major_number major,
350                rtems_device_minor_number minor,
351                void                      *arg)
352{
353  rtems_status_code              status;
354#ifndef USE_TASK_DRIVEN
355  static rtems_termios_callbacks cb =
356  {
357    NULL,                        /* firstOpen */
358    tty2_last_close,             /* lastClose */
359    NULL,                        /* poll read */
360    BSP_uart_termios_write_com2, /* write */
361    tty2_conSetAttr,             /* setAttributes */
362    NULL,                        /* stopRemoteTx */
363    NULL,                        /* startRemoteTx */
364    TERMIOS_IRQ_DRIVEN           /* outputUsesInterrupts */
365  };
366#else
367  static rtems_termios_callbacks cb =
368  {
369    NULL,                        /* firstOpen */
370    NULL,                        /* lastClose */
371    BSP_uart_termios_read_com2,  /* poll read */
372    BSP_uart_termios_write_com2, /* write */
373    tty2_conSetAttr,             /* setAttributes */
374    NULL,                        /* stopRemoteTx */
375    NULL,                        /* startRemoteTx */
376    TERMIOS_TASK_DRIVEN          /* outputUsesInterrupts */
377  };
378#endif
379
380  status = rtems_termios_open (major, minor, arg, &cb);
381  if(status != RTEMS_SUCCESSFUL)
382  {
383     printk("Error openning tty1 device\n");
384     return status;
385  }
386
387  /*
388   * Pass data area info down to driver
389   */
390  BSP_uart_termios_set( BSP_UART_COM2,
391                         ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
392   /* Enable interrupts  on channel */
393  BSP_uart_intr_ctrl( BSP_UART_COM2, BSP_UART_INTR_CTRL_TERMIOS);
394  return RTEMS_SUCCESSFUL;
395}
396
397/*
398 * Handle ioctl request for TTY2
399 */
400rtems_device_driver
401tty2_control(rtems_device_major_number major,
402                rtems_device_minor_number minor,
403                void                      * arg
404)
405{
406   return tty_control( BSP_UART_COM2, arg );
407}
408
409static int
410tty2_conSetAttr( int minor, const struct termios *t)
411{
412  return conSetAttr( BSP_UART_COM2, minor, t );
413}
Note: See TracBrowser for help on using the repository browser.