source: rtems/c/src/lib/libbsp/i386/shared/comm/tty_drv.c @ 529cebf0

4.104.114.84.9
Last change on this file since 529cebf0 was 529cebf0, checked in by Jennifer Averett <Jennifer.Averett@…>, on May 6, 2005 at 7:55:45 PM

2005-05-06 Jennifer Averett <jennifer.averett@…>

  • Makefile.am, comm/i386-stub-glue.c, comm/tty_drv.c, comm/uart.c, irq/idt.c, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c: Moved irq.h and irq_asm.h to bsp subdirectory.
  • Property mode set to 100644
File size: 13.8 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 * MODIFICATION/HISTORY:
19 *
20 * $Log$
21 * Revision 1.8  2005/05/03 14:45:12  jennifer
22 * 2005-05-03   Jennifer Averett <jennifer.averett@oarcorp.com>
23 *
24 *      * comm/tty_drv.c: Modified to support addition of parameter to ISRs.
25 *
26 * Revision 1.7  2004/04/21 16:01:33  ralf
27 * Remove duplicate white lines.
28 *
29 * Revision 1.6  2004/04/21 10:42:44  ralf
30 * Remove stray white spaces.
31 *
32 * Revision 1.5  2001/08/16 20:52:05  joel
33 * 2001-08-16   Mike Siers <mikes@poliac.com>
34 *
35 *      * comm/tty_drv.c, comm/uart.c: Correct some minor cut and paste bugs.
36 *
37 * Revision 1.4  2001/07/03 17:56:32  joel
38 * 2001-07-03   Mike Seirs <mike@poliac.com>
39 *
40 *      * comm/tty_drv.c, comm/uart.c, comm/uart.h:  Adds the capability
41 *      to use task driven serial I/O to ti386 BSPs. This patch leaves thex
42 *      default I/O mode to be IRQ.  If you want to use task I/O mode,
43 *      then the tty_drv.c file needs to be modified.  Basically, all
44 *      you need to change is the data values of the termios callbacks
45 *      structure.  This callback structure is used in the tty1_open
46 *      and tty2_open functions.  The values you need to set are commented
47 *      out in the source code.
48 *
49 * Revision 1.3  2000/12/05 16:37:38  joel
50 * 2000-12-01   Joel Sherrill <joel@OARcorp.com>
51 *
52 *      * pc386/console/console.c, pc386/console/serial_mouse.c,
53 *      pc386/console/vgainit.c, shared/comm/tty_drv.c: Remove warnings.
54 *
55 * Revision 1.2  2000/10/18 16:10:50  joel
56 * 2000-10-18    Charles-Antoine Gauthier <charles.gauthier@nrc.ca>
57 *
58 *      * comm/i386-stub-glue.c, comm/tty_drv.c, comm/uart.c, comm/uart.h:
59 *      Add the ability to set parity, number of data bits and
60 *      number of stop bits to the existing i386 serial drivers.
61 *
62 * Revision 1.1  2000/08/30 08:18:56  joel
63 * 2000-08-26  Rosimildo da Silva  <rdasilva@connecttel.com>
64 *
65 *      * shared/comm: Added "/dev/ttyS1" & "/dev/ttyS2" support for
66 *      the i386 BSPs.
67 *      * shared/comm/gdb_glue.c: New file.
68 *      * shared/comm/i386_io.c: New file.
69 *      * shared/comm/tty_drv.c: New file.
70 *      * shared/comm/tty_drv.h: New file.
71 *      * shared/comm/Makefile.am: Account for new files.
72 *      * shared/comm/uart.c: Adds support for sending characters to
73 *      another "line discipline."
74 *
75 ****************************************************************************/
76
77#include <stdio.h>
78#include <stdlib.h>
79#include <assert.h>
80
81#include <bsp.h>
82#include <bsp/irq.h>
83#include <rtems/libio.h>
84#include <rtems/termiostypes.h>
85#include <termios.h>
86#include <uart.h>
87#include <libcpu/cpuModel.h>
88
89int BSP_poll_read(int);
90
91/* Internal routines */
92static int tty1_conSetAttr( int minor, const struct termios *t);
93static int tty2_conSetAttr( int minor, const struct termios *t);
94static void isr_on(const rtems_irq_connect_data *);
95static void isr_off(const rtems_irq_connect_data *);
96static int  isr_is_on(const rtems_irq_connect_data *);
97
98extern BSP_polling_getchar_function_type BSP_poll_char;
99extern int BSPConsolePort;
100extern void rtems_set_waiting_id_comx( int port,  rtems_id id, rtems_event_set event );
101
102/*
103 * Interrupt structure for tty1
104 */
105static rtems_irq_connect_data tty1_isr_data =
106{
107  BSP_UART_COM1_IRQ,
108  BSP_uart_termios_isr_com1,
109  0,
110  isr_on,
111  isr_off,
112  isr_is_on};
113
114/*
115 * Interrupt structure for tty2
116 */
117static rtems_irq_connect_data tty2_isr_data =
118{
119  BSP_UART_COM2_IRQ,
120  BSP_uart_termios_isr_com2,
121  0,
122  isr_on,
123  isr_off,
124  isr_is_on};
125
126static void
127isr_on(const rtems_irq_connect_data *unused)
128{
129  return;
130}
131
132static void
133isr_off(const rtems_irq_connect_data *unused)
134{
135  return;
136}
137
138static int
139isr_is_on(const rtems_irq_connect_data *irq)
140{
141  return BSP_irq_enabled_at_i8259s(irq->name);
142}
143
144void tty_reserve_resources(rtems_configuration_table *conf)
145{
146  rtems_termios_reserve_resources(conf, 1);
147  return;
148}
149
150/*
151 *  TTYS1 - device driver INITIALIZE entry point.
152 */
153rtems_device_driver
154tty1_initialize(rtems_device_major_number major,
155                   rtems_device_minor_number minor,
156                   void                      *arg)
157{
158  rtems_status_code status;
159
160  /* Check if this port is not been used as console */
161  if( BSPConsolePort == BSP_UART_COM1 )
162  {
163    status = -1;
164    printk("TTYS1: port selected as console.\n");
165    rtems_fatal_error_occurred( status );
166  }
167
168  /*
169   * Set up TERMIOS
170   */
171  rtems_termios_initialize();
172
173  /*
174   * Do device-specific initialization
175   */
176  /* 9600-8-N-1, without hardware flow control */
177  BSP_uart_init( BSP_UART_COM1, 9600, CHR_8_BITS, 0, 0, 0 );
178  status = BSP_install_rtems_irq_handler( &tty1_isr_data );
179  if( !status )
180  {
181    printk("Error installing ttyS1 interrupt handler!\n");
182    rtems_fatal_error_occurred(status);
183  }
184  /*
185   * Register the device
186   */
187  status = rtems_io_register_name ("/dev/ttyS1", major, 0);
188  if (status != RTEMS_SUCCESSFUL)
189  {
190      printk("Error registering ttyS1 device!\n");
191      rtems_fatal_error_occurred (status);
192  }
193  printk("Device: /dev/ttyS1 initialized.\n");
194  return RTEMS_SUCCESSFUL;
195} /* tty_initialize */
196
197static int tty1_last_close(int major, int minor, void *arg)
198{
199  BSP_remove_rtems_irq_handler( &tty1_isr_data );
200  return 0;
201}
202
203/*
204 * TTY1 - device driver OPEN entry point
205 */
206rtems_device_driver
207tty1_open(rtems_device_major_number major,
208                rtems_device_minor_number minor,
209                void                      *arg)
210{
211  rtems_status_code  status;
212#ifndef USE_TASK_DRIVEN
213  static rtems_termios_callbacks cb =
214  {
215    NULL,                        /* firstOpen */
216    tty1_last_close,             /* lastClose */
217    NULL,                        /* poll read */
218    BSP_uart_termios_write_com1, /* write */
219    tty1_conSetAttr,             /* setAttributes */
220    NULL,                        /* stopRemoteTx */
221    NULL,                        /* startRemoteTx */
222    TERMIOS_IRQ_DRIVEN           /* outputUsesInterrupts */
223  };
224#else
225  static rtems_termios_callbacks cb =
226  {
227    NULL,                        /* firstOpen */
228    NULL,                        /* lastClose */
229    BSP_uart_termios_read_com1,  /* poll read */
230    BSP_uart_termios_write_com1, /* write */
231    tty1_conSetAttr,             /* setAttributes */
232    NULL,                        /* stopRemoteTx */
233    NULL,                        /* startRemoteTx */
234    TERMIOS_TASK_DRIVEN          /* outputUsesInterrupts */
235  };
236#endif
237
238  status = rtems_termios_open( major, minor, arg, &cb );
239  if(status != RTEMS_SUCCESSFUL)
240  {
241     printk("Error openning tty1 device\n");
242     return status;
243  }
244
245  /*
246   * Pass data area info down to driver
247   */
248  BSP_uart_termios_set( BSP_UART_COM1,
249                       ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
250  /* Enable interrupts  on channel */
251  BSP_uart_intr_ctrl( BSP_UART_COM1, BSP_UART_INTR_CTRL_TERMIOS);
252  return RTEMS_SUCCESSFUL;
253}
254
255/*
256 * TTY - device driver CLOSE entry point
257 */
258rtems_device_driver
259tty_close(rtems_device_major_number major,
260              rtems_device_minor_number minor,
261              void                      *arg)
262{
263
264  return (rtems_termios_close (arg));
265
266} /* tty_close */
267
268/*
269 * TTY device driver READ entry point.
270 * Read characters from the tty device.
271 */
272rtems_device_driver
273tty_read(rtems_device_major_number major,
274             rtems_device_minor_number minor,
275             void                      *arg)
276{
277  return rtems_termios_read (arg);
278} /* tty_read */
279
280/*
281 * TTY device driver WRITE entry point.
282 * Write characters to the tty device.
283 */
284rtems_device_driver
285tty_write(rtems_device_major_number major,
286              rtems_device_minor_number minor,
287              void                    * arg)
288{
289    return rtems_termios_write (arg);
290
291} /* tty_write */
292
293/*
294 * Handle ioctl request. This is a generic internal
295 * routine to handle both devices.
296 */
297static rtems_device_driver tty_control( int port, void  *arg )
298{
299        rtems_libio_ioctl_args_t *args = arg;
300        switch( args->command )
301        {
302           default:
303      return rtems_termios_ioctl (arg);
304                break;
305   }
306        args->ioctl_return = 0;
307   return RTEMS_SUCCESSFUL;
308}
309
310/*
311 * Handle ioctl request for ttyS1.
312 */
313rtems_device_driver
314tty1_control(rtems_device_major_number major,
315                rtems_device_minor_number minor,
316                void                      * arg
317)
318{
319  return tty_control( BSP_UART_COM1, arg );
320}
321
322static int
323conSetAttr(int port, int minor, const struct termios *t)
324{
325  unsigned long baud, databits, parity, stopbits;
326
327  switch (t->c_cflag & CBAUD)
328    {
329    case B50:
330      baud = 50;
331      break;
332    case B75:
333      baud = 75;
334      break;
335    case B110:
336      baud = 110;
337      break;
338    case B134:
339      baud = 134;
340      break;
341    case B150:
342      baud = 150;
343      break;
344    case B200:
345      baud = 200;
346      break;
347    case B300:
348      baud = 300;
349      break;
350    case B600:
351      baud = 600;
352      break;
353    case B1200:
354      baud = 1200;
355      break;
356    case B1800:
357      baud = 1800;
358      break;
359    case B2400:
360      baud = 2400;
361      break;
362    case B4800:
363      baud = 4800;
364      break;
365    case B9600:
366      baud = 9600;
367      break;
368    case B19200:
369      baud = 19200;
370      break;
371    case B38400:
372      baud = 38400;
373      break;
374    case B57600:
375      baud = 57600;
376      break;
377    case B115200:
378      baud = 115200;
379      break;
380    default:
381      baud = 0;
382      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
383      return 0;
384    }
385  if (t->c_cflag & PARENB) {
386    /* Parity is enabled */
387    if (t->c_cflag & PARODD) {
388      /* Parity is odd */
389      parity = PEN;
390    }
391    else {
392      /* Parity is even */
393      parity = PEN | EPS;
394    }
395  }
396  else {
397    /* No parity */
398    parity = 0;
399  }
400
401  switch (t->c_cflag & CSIZE) {
402    case CS5: databits = CHR_5_BITS; break;
403    case CS6: databits = CHR_6_BITS; break;
404    case CS7: databits = CHR_7_BITS; break;
405    default:  /* just to avoid warnings -- all cases are covered */
406    case CS8: databits = CHR_8_BITS; break;
407  }
408
409  if (t->c_cflag & CSTOPB) {
410    /* 2 stop bits */
411    stopbits = STB;
412  }
413  else {
414    /* 1 stop bit */
415    stopbits = 0;
416  }
417
418  printk("Setting attributes, port=%X, baud=%d, linemode = 0x%02x\n", port, baud, databits | parity | stopbits );
419  BSP_uart_set_attributes(port, baud, databits, parity, stopbits);
420  return 0;
421}
422
423/*
424 * Handle ioctl request for ttyS2.
425 */
426static int
427tty1_conSetAttr( int minor, const struct termios *t)
428{
429  return conSetAttr( BSP_UART_COM1, minor, t );
430}
431
432/*
433 * TTY2 device driver INITIALIZE entry point.
434 */
435rtems_device_driver
436tty2_initialize(rtems_device_major_number major,
437                   rtems_device_minor_number minor,
438                   void                      *arg)
439{
440  rtems_status_code status;
441
442  /* Check if this port is not been used as console */
443  if( BSPConsolePort == BSP_UART_COM2 )
444  {
445    status = -1;
446    printk("TTY2: port selected as console.\n");
447    rtems_fatal_error_occurred( status );
448  }
449
450  /*
451   * Set up TERMIOS
452   */
453  rtems_termios_initialize();
454
455  /*
456   * Do device-specific initialization
457   */
458  /* 9600-8-N-1, without hardware flow control */
459  BSP_uart_init( BSP_UART_COM2, 9600, CHR_8_BITS, 0, 0, 0);
460  status = BSP_install_rtems_irq_handler( &tty2_isr_data );
461  if( !status )
462  {
463    printk("Error installing serial console interrupt handler!\n");
464    rtems_fatal_error_occurred(status);
465  }
466  /*
467   * Register the device
468   */
469  status = rtems_io_register_name ("/dev/ttyS2", major, 0);
470  if (status != RTEMS_SUCCESSFUL)
471  {
472      printk("Error registering tty2 device!\n");
473      rtems_fatal_error_occurred (status);
474  }
475  printk("Device: /dev/ttyS2 initialized.\n");
476  return RTEMS_SUCCESSFUL;
477} /* tty_initialize */
478
479static int tty2_last_close(int major, int minor, void *arg)
480{
481  BSP_remove_rtems_irq_handler( &tty2_isr_data );
482  return 0;
483}
484
485/*
486 * TTY2 device driver OPEN entry point
487 */
488rtems_device_driver
489tty2_open(rtems_device_major_number major,
490                rtems_device_minor_number minor,
491                void                      *arg)
492{
493  rtems_status_code              status;
494#ifndef USE_TASK_DRIVEN
495  static rtems_termios_callbacks cb =
496  {
497    NULL,                        /* firstOpen */
498    tty2_last_close,             /* lastClose */
499    NULL,                        /* poll read */
500    BSP_uart_termios_write_com2, /* write */
501    tty2_conSetAttr,             /* setAttributes */
502    NULL,                        /* stopRemoteTx */
503    NULL,                        /* startRemoteTx */
504    TERMIOS_IRQ_DRIVEN           /* outputUsesInterrupts */
505  };
506#else
507  static rtems_termios_callbacks cb =
508  {
509    NULL,                        /* firstOpen */
510    NULL,                        /* lastClose */
511    BSP_uart_termios_read_com2,  /* poll read */
512    BSP_uart_termios_write_com2, /* write */
513    tty2_conSetAttr,             /* setAttributes */
514    NULL,                        /* stopRemoteTx */
515    NULL,                        /* startRemoteTx */
516    TERMIOS_TASK_DRIVEN          /* outputUsesInterrupts */
517  };
518#endif
519
520  status = rtems_termios_open (major, minor, arg, &cb);
521  if(status != RTEMS_SUCCESSFUL)
522  {
523     printk("Error openning tty1 device\n");
524     return status;
525  }
526
527  /*
528   * Pass data area info down to driver
529   */
530  BSP_uart_termios_set( BSP_UART_COM2,
531                         ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
532   /* Enable interrupts  on channel */
533  BSP_uart_intr_ctrl( BSP_UART_COM2, BSP_UART_INTR_CTRL_TERMIOS);
534  return RTEMS_SUCCESSFUL;
535}
536
537/*
538 * Handle ioctl request for TTY2
539 */
540rtems_device_driver
541tty2_control(rtems_device_major_number major,
542                rtems_device_minor_number minor,
543                void                      * arg
544)
545{
546   return tty_control( BSP_UART_COM2, arg );
547}
548
549static int
550tty2_conSetAttr( int minor, const struct termios *t)
551{
552  return conSetAttr( BSP_UART_COM2, minor, t );
553}
Note: See TracBrowser for help on using the repository browser.