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

4.115
Last change on this file since cdc0560 was cdc0560, checked in by Sebastian Huber <sebastian.huber@…>, on 02/01/11 at 15:48:26

2011-02-01 Sebastian Huber <sebastian.huber@…>

  • console.c: Flow control is optional.
  • Property mode set to 100644
File size: 7.1 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 <stdlib.h>
20#include <assert.h>
21#include <termios.h>
22
23#include <rtems/termiostypes.h>
24#include <libchip/serial.h>
25
26/*
27 *  Configuration Information
28 */
29
30extern console_data  Console_Port_Data[];
31extern unsigned long  Console_Port_Count;
32extern rtems_device_minor_number  Console_Port_Minor;
33
34/*PAGE
35 *
36 *  console_open
37 *
38 *  open a port as a termios console.
39 *
40 */
41
42rtems_device_driver console_open(
43  rtems_device_major_number major,
44  rtems_device_minor_number minor,
45  void                    * arg
46)
47{
48  rtems_status_code              status;
49  rtems_libio_open_close_args_t *args = arg;
50  rtems_libio_ioctl_args_t       IoctlArgs;
51  struct termios                 Termios;
52  rtems_termios_callbacks        Callbacks;
53  console_tbl                   *cptr;
54  struct rtems_termios_tty      *current_tty;
55
56  /*
57   * Verify the port number is valid.
58   */
59  if ( minor > Console_Port_Count ) {
60    return RTEMS_INVALID_NUMBER;
61  }
62
63  /*
64   * Open the port as a termios console driver.
65   */
66
67  cptr = &Console_Port_Tbl[minor];
68  Callbacks.firstOpen            = cptr->pDeviceFns->deviceFirstOpen;
69  Callbacks.lastClose            = cptr->pDeviceFns->deviceLastClose;
70  Callbacks.pollRead             = cptr->pDeviceFns->deviceRead;
71  Callbacks.write                = cptr->pDeviceFns->deviceWrite;
72  Callbacks.setAttributes        = cptr->pDeviceFns->deviceSetAttributes;
73  if (cptr->pDeviceFlow != NULL) {
74    Callbacks.stopRemoteTx = cptr->pDeviceFlow->deviceStopRemoteTx;
75    Callbacks.startRemoteTx = cptr->pDeviceFlow->deviceStartRemoteTx;
76  } else {
77    Callbacks.stopRemoteTx = NULL;
78    Callbacks.startRemoteTx = NULL;
79  }
80  Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts;
81
82  /* XXX what about
83   *        Console_Port_Tbl[minor].ulMargin,
84   *        Console_Port_Tbl[minor].ulHysteresis);
85   */
86
87  status = rtems_termios_open ( major, minor, arg, &Callbacks );
88  Console_Port_Data[minor].termios_data = args->iop->data1;
89
90  /* Get tty pointur from the Console_Port_Data */
91  current_tty = Console_Port_Data[minor].termios_data;
92
93  if ( (current_tty->refcount == 1) ) {
94
95    /*
96     *  If this BSP has a preferred default rate, then use that.
97     */
98    #if defined(BSP_DEFAULT_BAUD_RATE)
99      rtems_termios_set_initial_baud( current_tty, BSP_DEFAULT_BAUD_RATE );
100    #endif
101
102    /*
103     * If it's the first open, modified, if need, the port parameters
104     */
105    if (minor!=Console_Port_Minor) {
106      /*
107       * If this is not the console we do not want ECHO and
108       * so forth
109       */
110      IoctlArgs.iop=args->iop;
111      IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
112      IoctlArgs.buffer=&Termios;
113      rtems_termios_ioctl(&IoctlArgs);
114      Termios.c_lflag=ICANON;
115      IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
116      rtems_termios_ioctl(&IoctlArgs);
117    }
118  }
119
120  if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
121      Console_Port_Tbl[minor].pDeviceFlow &&
122      Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx) {
123    Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
124  }
125
126  return status;
127}
128
129/*PAGE
130 *
131 *  console_close
132 *
133 *  This routine closes a port that has been opened as console.
134 */
135
136rtems_device_driver console_close(
137  rtems_device_major_number major,
138  rtems_device_minor_number minor,
139  void                    * arg
140)
141{
142  rtems_libio_open_close_args_t *args = arg;
143  struct rtems_termios_tty      *current_tty;
144
145  /* Get tty pointeur from the Console_Port_Data */
146  current_tty = Console_Port_Data[minor].termios_data;
147
148  /* Get the tty refcount to determine if we need to do deviceStopRemoteTx.
149   * Stop only if it's the last one opened.
150   */
151  if ( (current_tty->refcount == 1) ) {
152    if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
153          Console_Port_Tbl[minor].pDeviceFlow &&
154          Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx) {
155      Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
156    }
157  }
158
159  return rtems_termios_close (arg);
160}
161
162/*PAGE
163 *
164 *  console_read
165 *
166 *  This routine uses the termios driver to read a character.
167 */
168
169rtems_device_driver console_read(
170  rtems_device_major_number major,
171  rtems_device_minor_number minor,
172  void                    * arg
173)
174{
175  return rtems_termios_read (arg);
176}
177
178/*PAGE
179 *
180 *  console_write
181 *
182 *  this routine uses the termios driver to write a character.
183 */
184
185rtems_device_driver console_write(
186  rtems_device_major_number major,
187  rtems_device_minor_number minor,
188  void                    * arg
189)
190{
191  return rtems_termios_write (arg);
192}
193
194/*PAGE
195 *
196 *  console_control
197 *
198 *  this routine uses the termios driver to process io
199 */
200
201rtems_device_driver console_control(
202  rtems_device_major_number major,
203  rtems_device_minor_number minor,
204  void                    * arg
205)
206{
207  return rtems_termios_ioctl (arg);
208}
209
210/*PAGE
211 *
212 *  console_initialize
213 *
214 *  Routine called to initialize the console device driver.
215 */
216
217rtems_device_driver console_initialize(
218  rtems_device_major_number  major,
219  rtems_device_minor_number  minor_arg,
220  void                      *arg
221)
222{
223  rtems_status_code          status;
224  rtems_device_minor_number  minor;
225
226  /*
227   * initialize the termio interface.
228   */
229
230  rtems_termios_initialize();
231
232  for (minor=0; minor < Console_Port_Count ; minor++) {
233    /*
234     * First perform the configuration dependent probe, then the
235     * device dependent probe
236     */
237
238    if ((!Console_Port_Tbl[minor].deviceProbe ||
239         Console_Port_Tbl[minor].deviceProbe(minor)) &&
240         Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) {
241      /*
242       * Use this device for the console
243       */
244      break;
245    }
246  }
247  if ( minor == Console_Port_Count ) {
248    /*
249     * Failed to find a working device
250     */
251    rtems_fatal_error_occurred(RTEMS_IO_ERROR);
252  }
253
254  Console_Port_Minor=minor;
255
256  /*
257   * Register Device Names
258   */
259  status = rtems_io_register_name("/dev/console", major, Console_Port_Minor );
260  if (status != RTEMS_SUCCESSFUL) {
261    rtems_fatal_error_occurred(status);
262  }
263  Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(Console_Port_Minor);
264
265  for (minor++;minor<Console_Port_Count;minor++) {
266    /*
267     * First perform the configuration dependent probe, then the
268     * device dependent probe
269     */
270
271    if ( (!Console_Port_Tbl[minor].deviceProbe ||
272         Console_Port_Tbl[minor].deviceProbe(minor)) &&
273         Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) {
274      status = rtems_io_register_name(
275        Console_Port_Tbl[minor].sDeviceName,
276        major,
277        minor );
278      if (status != RTEMS_SUCCESSFUL) {
279        rtems_fatal_error_occurred(status);
280      }
281
282      /*
283       * Initialize the hardware device.
284       */
285
286      Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(minor);
287
288    }
289  }
290
291  return RTEMS_SUCCESSFUL;
292}
Note: See TracBrowser for help on using the repository browser.