source: rtems/c/src/lib/libbsp/shared/console.c @ c086044

4.115
Last change on this file since c086044 was c086044, checked in by Sebastian Huber <sebastian.huber@…>, on Mar 21, 2011 at 8:19:19 AM

2011-03-21 Sebastian Huber <sebastian.huber@…>

  • console.c: Make device file optional.
  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 *  This file contains the generic console driver shell used
3 *  by all console drivers using libchip.
4 *
5 *  This driver uses the termios pseudo driver.
6 *
7 *  COPYRIGHT (c) 1989-1997.
8 *  On-Line Applications Research Corporation (OAR).
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.rtems.com/license/LICENSE.
13 *
14 *  $Id$
15 */
16
17#include <bsp.h>
18#include <rtems/libio.h>
19#include <rtems/console.h>
20#include <stdlib.h>
21#include <assert.h>
22#include <termios.h>
23
24#include <rtems/termiostypes.h>
25#include <libchip/serial.h>
26
27/*
28 *  Configuration Information
29 */
30
31extern console_data  Console_Port_Data[];
32extern unsigned long  Console_Port_Count;
33extern rtems_device_minor_number  Console_Port_Minor;
34
35/*PAGE
36 *
37 *  console_open
38 *
39 *  open a port as a termios console.
40 *
41 */
42
43rtems_device_driver console_open(
44  rtems_device_major_number major,
45  rtems_device_minor_number minor,
46  void                    * arg
47)
48{
49  rtems_status_code              status;
50  rtems_libio_open_close_args_t *args = arg;
51  rtems_libio_ioctl_args_t       IoctlArgs;
52  struct termios                 Termios;
53  rtems_termios_callbacks        Callbacks;
54  console_tbl                   *cptr;
55  struct rtems_termios_tty      *current_tty;
56
57  /*
58   * Verify the port number is valid.
59   */
60  if ( minor > Console_Port_Count ) {
61    return RTEMS_INVALID_NUMBER;
62  }
63
64  /*
65   * Open the port as a termios console driver.
66   */
67
68  cptr = &Console_Port_Tbl[minor];
69  Callbacks.firstOpen            = cptr->pDeviceFns->deviceFirstOpen;
70  Callbacks.lastClose            = cptr->pDeviceFns->deviceLastClose;
71  Callbacks.pollRead             = cptr->pDeviceFns->deviceRead;
72  Callbacks.write                = cptr->pDeviceFns->deviceWrite;
73  Callbacks.setAttributes        = cptr->pDeviceFns->deviceSetAttributes;
74  if (cptr->pDeviceFlow != NULL) {
75    Callbacks.stopRemoteTx = cptr->pDeviceFlow->deviceStopRemoteTx;
76    Callbacks.startRemoteTx = cptr->pDeviceFlow->deviceStartRemoteTx;
77  } else {
78    Callbacks.stopRemoteTx = NULL;
79    Callbacks.startRemoteTx = NULL;
80  }
81  Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts;
82
83  /* XXX what about
84   *        Console_Port_Tbl[minor].ulMargin,
85   *        Console_Port_Tbl[minor].ulHysteresis);
86   */
87
88  status = rtems_termios_open ( major, minor, arg, &Callbacks );
89  Console_Port_Data[minor].termios_data = args->iop->data1;
90
91  /* Get tty pointur from the Console_Port_Data */
92  current_tty = Console_Port_Data[minor].termios_data;
93
94  if ( (current_tty->refcount == 1) ) {
95
96    /*
97     *  If this BSP has a preferred default rate, then use that.
98     */
99    #if defined(BSP_DEFAULT_BAUD_RATE)
100      rtems_termios_set_initial_baud( current_tty, BSP_DEFAULT_BAUD_RATE );
101    #endif
102
103    /*
104     * If it's the first open, modified, if need, the port parameters
105     */
106    if (minor!=Console_Port_Minor) {
107      /*
108       * If this is not the console we do not want ECHO and
109       * so forth
110       */
111      IoctlArgs.iop=args->iop;
112      IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
113      IoctlArgs.buffer=&Termios;
114      rtems_termios_ioctl(&IoctlArgs);
115      Termios.c_lflag=ICANON;
116      IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
117      rtems_termios_ioctl(&IoctlArgs);
118    }
119  }
120
121  if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
122      Console_Port_Tbl[minor].pDeviceFlow &&
123      Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx) {
124    Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
125  }
126
127  return status;
128}
129
130/*PAGE
131 *
132 *  console_close
133 *
134 *  This routine closes a port that has been opened as console.
135 */
136
137rtems_device_driver console_close(
138  rtems_device_major_number major,
139  rtems_device_minor_number minor,
140  void                    * arg
141)
142{
143  rtems_libio_open_close_args_t *args = arg;
144  struct rtems_termios_tty      *current_tty;
145
146  /* Get tty pointeur from the Console_Port_Data */
147  current_tty = Console_Port_Data[minor].termios_data;
148
149  /* Get the tty refcount to determine if we need to do deviceStopRemoteTx.
150   * Stop only if it's the last one opened.
151   */
152  if ( (current_tty->refcount == 1) ) {
153    if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
154          Console_Port_Tbl[minor].pDeviceFlow &&
155          Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx) {
156      Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
157    }
158  }
159
160  return rtems_termios_close (arg);
161}
162
163/*PAGE
164 *
165 *  console_read
166 *
167 *  This routine uses the termios driver to read a character.
168 */
169
170rtems_device_driver console_read(
171  rtems_device_major_number major,
172  rtems_device_minor_number minor,
173  void                    * arg
174)
175{
176  return rtems_termios_read (arg);
177}
178
179/*PAGE
180 *
181 *  console_write
182 *
183 *  this routine uses the termios driver to write a character.
184 */
185
186rtems_device_driver console_write(
187  rtems_device_major_number major,
188  rtems_device_minor_number minor,
189  void                    * arg
190)
191{
192  return rtems_termios_write (arg);
193}
194
195/*PAGE
196 *
197 *  console_control
198 *
199 *  this routine uses the termios driver to process io
200 */
201
202rtems_device_driver console_control(
203  rtems_device_major_number major,
204  rtems_device_minor_number minor,
205  void                    * arg
206)
207{
208  return rtems_termios_ioctl (arg);
209}
210
211/*PAGE
212 *
213 *  console_initialize
214 *
215 *  Routine called to initialize the console device driver.
216 */
217
218rtems_device_driver console_initialize(
219  rtems_device_major_number  major,
220  rtems_device_minor_number  minor,
221  void                      *arg
222)
223{
224  rtems_status_code sc = RTEMS_SUCCESSFUL;
225  bool first = true;
226
227  rtems_termios_initialize();
228
229  for (minor = 0; minor < Console_Port_Count; ++minor) {
230    const console_tbl *device = &Console_Port_Tbl [minor];
231
232    if (
233      (device->deviceProbe == NULL || device->deviceProbe(minor))
234        && device->pDeviceFns->deviceProbe(minor)
235    ) {
236      device->pDeviceFns->deviceInitialize(minor);
237      if (first) {
238        first = false;
239        Console_Port_Minor = minor;
240        sc = rtems_io_register_name(CONSOLE_DEVICE_NAME, major, minor);
241        if (sc != RTEMS_SUCCESSFUL) {
242          rtems_fatal_error_occurred(sc);
243        }
244      }
245      if (device->sDeviceName != NULL) {
246        sc = rtems_io_register_name(device->sDeviceName, major, minor);
247        if (sc != RTEMS_SUCCESSFUL) {
248          rtems_fatal_error_occurred(sc);
249        }
250      }
251    }
252  }
253
254  if (first) {
255    /*
256     * Failed to find a working device
257     */
258    rtems_fatal_error_occurred(RTEMS_IO_ERROR);
259  }
260
261  return RTEMS_SUCCESSFUL;
262}
Note: See TracBrowser for help on using the repository browser.