source: rtems/c/src/lib/libbsp/i386/shared/comm/tty_drv.c @ 675167c6

4.104.114.95
Last change on this file since 675167c6 was 675167c6, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 23, 2008 at 9:50:37 PM

2008-04-23 Joel Sherrill <joel.sherrill@…>

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