source: rtems/c/src/lib/libbsp/i386/shared/comm/tty_drv.c @ 45ca51c

4.115
Last change on this file since 45ca51c was 2bdcf4fd, checked in by Vipul Nayyar <nayyar_vipul@…>, on 07/26/13 at 14:53:39

Updated legacy code in i386 pc386

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