source: rtems/c/src/lib/libbsp/sh/gensh4/console/console.c @ 25ddacd

4.104.11
Last change on this file since 25ddacd was 25ddacd, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 20, 2010 at 8:13:58 AM

2010-04-20 Ralf Corsépius <ralf.corsepius@…>

  • console/console.c: Reflect termios-API having changed.
  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*
2 * Console driver for SH-4 UART modules
3 *
4 * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
5 * Author: Alexandra Kossovsky <sasha@oktet.ru>
6 *
7 *  COPYRIGHT (c) 1989-1998.
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 *
13 *  http://www.rtems.com/license/LICENSE.
14 *
15 *  $Id$
16 */
17
18#include <bsp.h>
19
20#include <termios.h>
21#include <rtems/libio.h>
22#include "sh/sh4uart.h"
23
24/* Descriptor structures for two on-chip UART channels */
25sh4uart sh4_uarts[2];
26
27/* Console operations mode:
28 *     0 - raw (non-termios) polled input/output
29 *     1 - termios-based polled input/output
30 *     2 - termios-based interrupt-driven input/output
31 *     3 - non-termios over gdb stub
32 */
33int console_mode = 3;
34#define CONSOLE_MODE_RAW  (0)
35#define CONSOLE_MODE_POLL (1)
36#define CONSOLE_MODE_INT  (2)
37#define CONSOLE_MODE_IPL  (3)
38
39/* Wrapper functions for SH-4 UART generic driver */
40
41/* console_poll_read --
42 *     wrapper for poll read function
43 *
44 * PARAMETERS:
45 *     minor - minor device number
46 *
47 * RETURNS:
48 *     character code readed from UART, or -1 if there is no characters
49 *     available
50 */
51static int
52console_poll_read(int minor)
53{
54        return sh4uart_poll_read(&sh4_uarts[minor]);
55}
56
57/* console_interrupt_write --
58 *     wrapper for interrupt write function
59 *
60 * PARAMETERS:
61 *     minor - minor device number
62 *     buf - output buffer
63 *     len - output buffer length
64 *
65 * RETURNS:
66 *     result code
67 */
68static ssize_t
69console_interrupt_write(int minor, const char *buf, size_t len)
70{
71        return sh4uart_interrupt_write(&sh4_uarts[minor], buf, len);
72}
73
74/* console_poll_write --
75 *     wrapper for polling mode write function
76 *
77 * PARAMETERS:
78 *     minor - minor device number
79 *     buf - output buffer
80 *     len - output buffer length
81 *
82 * RETURNS:
83 *     result code
84 */
85static ssize_t
86console_poll_write(int minor, const char *buf, size_t len)
87{
88        return sh4uart_poll_write(&sh4_uarts[minor], buf, len);
89}
90
91/* console_set_attributes --
92 *     wrapper for hardware-dependent termios attributes setting
93 *
94 * PARAMETERS:
95 *     minor - minor device number
96 *     t - pointer to the termios structure
97 *
98 * RETURNS:
99 *     result code
100 */
101static int
102console_set_attributes(int minor, const struct termios *t)
103{
104        return sh4uart_set_attributes(&sh4_uarts[minor], t);
105}
106
107/* console_stop_remote_tx --
108 *     wrapper for stopping data flow from remote party.
109 *
110 * PARAMETERS:
111 *     minor - minor device number
112 *
113 * RETURNS:
114 *     result code
115 */
116static int
117console_stop_remote_tx(int minor)
118{
119    if (minor < sizeof(sh4_uarts)/sizeof(sh4_uarts[0]))
120        return sh4uart_stop_remote_tx(&sh4_uarts[minor]);
121    else
122        return RTEMS_INVALID_NUMBER;
123}
124
125/* console_start_remote_tx --
126 *     wrapper for resuming data flow from remote party.
127 *
128 * PARAMETERS:
129 *     minor - minor device number
130 *
131 */
132static int
133console_start_remote_tx(int minor)
134{
135    if (minor < sizeof(sh4_uarts)/sizeof(sh4_uarts[0]))
136        return sh4uart_start_remote_tx(&sh4_uarts[minor]);
137    else
138        return RTEMS_INVALID_NUMBER;
139}
140
141/* console_first_open --
142 *     wrapper for UART controller initialization functions
143 *
144 * PARAMETERS:
145 *     major - major device number
146 *     minor - minor device number
147 *     arg - libio device open argument
148 *
149 * RETURNS:
150 *     error code
151 */
152static int
153console_first_open(int major, int minor, void *arg)
154{
155    rtems_libio_open_close_args_t *args = arg;
156    rtems_status_code sc;
157
158    sc = sh4uart_init(&sh4_uarts[minor], /* uart */
159            args->iop->data1,       /* tty */
160            minor+1,                /* channel */
161            (console_mode == CONSOLE_MODE_INT));
162
163    if (sc == RTEMS_SUCCESSFUL)
164        sc = sh4uart_reset(&sh4_uarts[minor]);
165
166    return sc;
167}
168
169/* console_last_close --
170 *     wrapper for UART controller close function
171 *
172 * PARAMETERS:
173 *     major - major device number
174 *     minor - minor device number
175 *     arg - libio device close argument
176 *
177 * RETURNS:
178 *     error code
179 */
180static int
181console_last_close(int major, int minor, void *arg)
182{
183    if (console_mode != CONSOLE_MODE_IPL)
184    /* working from gdb we should not disable port operations */
185        return sh4uart_disable(&sh4_uarts[minor],
186                !(boot_mode == SH4_BOOT_MODE_IPL));
187    else
188        return RTEMS_SUCCESSFUL;
189}
190
191/* console_initialize --
192 *     This routine initializes the console IO drivers and register devices
193 *     in RTEMS I/O system.
194 *
195 * PARAMETERS:
196 *     major - major console device number
197 *     minor - minor console device number (not used)
198 *     arg - device initialize argument
199 *
200 * RETURNS:
201 *     RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
202 */
203rtems_device_driver
204console_initialize(rtems_device_major_number major,
205        rtems_device_minor_number minor,
206        void *arg)
207{
208    rtems_status_code status;
209
210#ifdef SH4_WITH_IPL
211    /* booting from flash we cannot have IPL console */
212    if (boot_mode != SH4_BOOT_MODE_IPL && console_mode == CONSOLE_MODE_IPL)
213        console_mode = CONSOLE_MODE_INT;
214
215    /* break out from gdb if neccessary */
216    if (boot_mode == SH4_BOOT_MODE_IPL && console_mode != CONSOLE_MODE_IPL)
217        ipl_finish();
218#endif
219
220    /*
221     * Set up TERMIOS
222     */
223    if ((console_mode != CONSOLE_MODE_RAW) &&
224                    (console_mode != CONSOLE_MODE_IPL))
225        rtems_termios_initialize ();
226
227    /*
228     * Register the devices
229     */
230    status = rtems_io_register_name ("/dev/console", major, 0);
231    if (status != RTEMS_SUCCESSFUL)
232        rtems_fatal_error_occurred (status);
233
234    status = rtems_io_register_name ("/dev/aux", major, 1);
235    if (status != RTEMS_SUCCESSFUL)
236        rtems_fatal_error_occurred (status);
237
238    if (console_mode == CONSOLE_MODE_RAW)
239    {
240        rtems_status_code sc;
241        sc = sh4uart_init(&sh4_uarts[0],              /* uart */
242                NULL,                  /* tty */
243                1,                     /* UART channel number */
244                0);                    /* Poll-mode */
245
246        if (sc == RTEMS_SUCCESSFUL)
247            sc = sh4uart_reset(&sh4_uarts[0]);
248
249        sc = sh4uart_init(&sh4_uarts[1],              /* uart */
250                NULL,                  /* tty */
251                2,                     /* UART channel number */
252                0);                    /* Poll-mode */
253
254        if (sc == RTEMS_SUCCESSFUL)
255            sc = sh4uart_reset(&sh4_uarts[1]);
256
257        return sc;
258    }
259
260    return RTEMS_SUCCESSFUL;
261}
262
263/* console_open --
264 *     Open console device driver. Pass appropriate termios callback
265 *     functions to termios library.
266 *
267 * PARAMETERS:
268 *     major - major device number for console devices
269 *     minor - minor device number for console
270 *     arg - device opening argument
271 *
272 * RETURNS:
273 *     RTEMS error code
274 */
275rtems_device_driver
276console_open(rtems_device_major_number major,
277        rtems_device_minor_number minor,
278        void *arg)
279{
280    static const rtems_termios_callbacks intr_callbacks = {
281        console_first_open,        /* firstOpen */
282        console_last_close,        /* lastClose */
283        NULL,                      /* pollRead */
284        console_interrupt_write,   /* write */
285        console_set_attributes,    /* setAttributes */
286        console_stop_remote_tx,    /* stopRemoteTx */
287        console_start_remote_tx,   /* startRemoteTx */
288        1                          /* outputUsesInterrupts */
289    };
290    static const rtems_termios_callbacks poll_callbacks = {
291        console_first_open,        /* firstOpen */
292        console_last_close,        /* lastClose */
293        console_poll_read,         /* pollRead */
294        console_poll_write,        /* write */
295        console_set_attributes,    /* setAttributes */
296        console_stop_remote_tx,    /* stopRemoteTx */
297        console_start_remote_tx,   /* startRemoteTx */
298        0                          /* outputUsesInterrupts */
299    };
300
301    switch (console_mode)
302    {
303        case CONSOLE_MODE_RAW:
304        case CONSOLE_MODE_IPL:
305            return RTEMS_SUCCESSFUL;
306
307        case CONSOLE_MODE_INT:
308            return rtems_termios_open(major, minor, arg, &intr_callbacks);
309
310        case CONSOLE_MODE_POLL:
311            return rtems_termios_open(major, minor, arg, &poll_callbacks);
312
313        default:
314            rtems_fatal_error_occurred(0xC07A1310);
315    }
316
317    return RTEMS_INTERNAL_ERROR;
318}
319
320/* console_close --
321 *     Close console device.
322 *
323 * PARAMETERS:
324 *     major - major device number for console devices
325 *     minor - minor device number for console
326 *     arg - device close argument
327 *
328 * RETURNS:
329 *     RTEMS error code
330 */
331rtems_device_driver
332console_close(rtems_device_major_number major,
333        rtems_device_minor_number minor,
334        void *arg)
335{
336    if ((console_mode != CONSOLE_MODE_RAW) &&
337            (console_mode != CONSOLE_MODE_IPL))
338        return rtems_termios_close (arg);
339    else
340        return RTEMS_SUCCESSFUL;
341}
342
343/* console_read --
344 *     Read from the console device
345 *
346 * PARAMETERS:
347 *     major - major device number for console devices
348 *     minor - minor device number for console
349 *     arg - device read argument
350 *
351 * RETURNS:
352 *     RTEMS error code
353 */
354rtems_device_driver
355console_read(rtems_device_major_number major,
356        rtems_device_minor_number minor,
357        void *arg)
358{
359    if ((console_mode != CONSOLE_MODE_RAW) &&
360            (console_mode != CONSOLE_MODE_IPL))
361    {
362        return rtems_termios_read (arg);
363    }
364    else
365    {
366        rtems_libio_rw_args_t *argp = arg;
367        char *buf = argp->buffer;
368        int count = argp->count;
369        int n = 0;
370        int c;
371        while (n < count)
372        {
373            do {
374                c = (console_mode == CONSOLE_MODE_RAW) ?
375                        sh4uart_poll_read(&sh4_uarts[minor]) :
376                        ipl_console_poll_read(minor);
377            } while (c == -1);
378            if (c == '\r')
379                c = '\n';
380            *(buf++) = c;
381            n++;
382            if (c == '\n')
383                break;
384        }
385        argp->bytes_moved = n;
386        return RTEMS_SUCCESSFUL;
387    }
388}
389
390/* console_write --
391 *     Write to the console device
392 *
393 * PARAMETERS:
394 *     major - major device number for console devices
395 *     minor - minor device number for console
396 *     arg - device write argument
397 *
398 * RETURNS:
399 *     RTEMS error code
400 */
401rtems_device_driver
402console_write(rtems_device_major_number major,
403        rtems_device_minor_number minor,
404        void *arg)
405{
406    switch (console_mode)
407    {
408        case CONSOLE_MODE_POLL:
409        case CONSOLE_MODE_INT:
410                return rtems_termios_write (arg);
411        case CONSOLE_MODE_RAW:
412        {
413            rtems_libio_rw_args_t *argp = arg;
414            char cr = '\r';
415            char *buf = argp->buffer;
416            int count = argp->count;
417            int i;
418
419            for (i = 0; i < count; i++)
420            {
421                if (*buf == '\n')
422                    sh4uart_poll_write(&sh4_uarts[minor], &cr, 1);
423                sh4uart_poll_write(&sh4_uarts[minor], buf, 1);
424                buf++;
425            }
426            argp->bytes_moved = count;
427            return RTEMS_SUCCESSFUL;
428        }
429#ifdef SH4_WITH_IPL
430        case CONSOLE_MODE_IPL:
431        {
432            rtems_libio_rw_args_t *argp = arg;
433            char *buf = argp->buffer;
434            int count = argp->count;
435            ipl_console_poll_write(minor, buf, count);
436            argp->bytes_moved = count;
437            return RTEMS_SUCCESSFUL;
438        }
439#endif
440        default: /* Unreachable */
441            return RTEMS_NOT_DEFINED;
442    }
443}
444
445/* console_control --
446 *     Handle console device I/O control (IOCTL)
447 *
448 * PARAMETERS:
449 *     major - major device number for console devices
450 *     minor - minor device number for console
451 *     arg - device ioctl argument
452 *
453 * RETURNS:
454 *     RTEMS error code
455 */
456rtems_device_driver
457console_control(rtems_device_major_number major,
458        rtems_device_minor_number minor,
459        void *arg)
460{
461    if ((console_mode != CONSOLE_MODE_RAW) &&
462            (console_mode != CONSOLE_MODE_IPL))
463    {
464        return rtems_termios_ioctl (arg);
465    }
466    else
467    {
468        return RTEMS_SUCCESSFUL;
469    }
470}
Note: See TracBrowser for help on using the repository browser.