source: rtems/c/src/exec/libcsupport/src/termios.c @ 52e1708

4.104.114.84.95
Last change on this file since 52e1708 was 52e1708, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 10, 1997 at 5:31:11 PM

Set return code to avoid spurious errors.

  • Property mode set to 100644
File size: 17.4 KB
Line 
1/*
2 * TERMIOS serial line support
3 *
4 *  Authors:
5 *    W. Eric Norum
6 *    Saskatchewan Accelerator Laboratory
7 *    University of Saskatchewan
8 *    Saskatoon, Saskatchewan, CANADA
9 *    eric@skatter.usask.ca
10 *
11 *    AND
12 *
13 *    Katsutoshi Shibuya
14 *    BU Denken Co.,Ltd.
15 *    Sapporo, JAPAN
16 *    shibuya@mxb.meshnet.or.jp
17 *
18 *  The license and distribution terms for this file may be
19 *  found in the file LICENSE in this distribution or at
20 *  http://www.OARcorp.com/rtems/license.html.
21 *
22 *  $Id$
23 */
24
25#include <rtems.h>
26#include <rtems/libio.h>
27#include <ctype.h>
28#include <errno.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <termios.h>
32#include <unistd.h>
33
34/*
35 * The size of the cooked buffer
36 */
37#define CBUFSIZE        256
38
39/*
40 * The size of the raw input message queue
41 */
42#define RAW_BUFFER_SIZE 128
43
44/*
45 * Variables associated with each termios instance.
46 * One structure for each hardware I/O device.
47 */
48struct rtems_termios_tty {
49        /*
50         * Linked-list of active TERMIOS devices
51         */
52        struct rtems_termios_tty        *forw;
53        struct rtems_termios_tty        *back;
54
55        /*
56         * How many times has this device been opened
57         */
58        int             refcount;
59
60        /*
61         * This device
62         */
63        rtems_device_major_number       major;
64        rtems_device_major_number       minor;
65
66        /*
67         * Mutual-exclusion semaphores
68         */
69        rtems_id        isem;
70        rtems_id        osem;
71
72        /*
73         * The canonical (cooked) character buffer
74         */
75        char            cbuf[CBUFSIZE];
76        int             ccount;
77        int             cindex;
78
79        /*
80         * Keep track of cursor (printhead) position
81         */
82        int             column;
83        int             read_start_column;
84
85        /*
86         * The ioctl settings
87         */
88        struct termios  termios;
89        rtems_interval  vtimeTicks;
90
91        /*
92         * Raw character buffer
93         */
94        volatile char           rawBuf[RAW_BUFFER_SIZE];
95        volatile unsigned int   rawBufHead;
96        volatile unsigned int   rawBufTail;
97        rtems_id                rawBufSemaphore;
98        rtems_unsigned32        rawBufSemaphoreOptions;
99        rtems_interval          rawBufSemaphoreTimeout;
100        rtems_interval          rawBufSemaphoreFirstTimeout;
101        unsigned int            rawBufDropped;  /* Statistics */
102
103        /*
104         * Callbacks to device-specific routines
105         */
106        int             (*lastClose)(int major, int minor, void *arg);
107        int             (*read)(int minor);
108        int             (*write)(int minor, char *buf, int len);
109};
110static struct rtems_termios_tty *ttyHead, *ttyTail;
111static rtems_id ttyMutex;
112
113void
114rtems_termios_initialize (void)
115{
116        rtems_status_code sc;
117
118        /*
119         * Create the mutex semaphore for the tty list
120         */
121        if (!ttyMutex) {
122                sc = rtems_semaphore_create (
123                        rtems_build_name ('T', 'R', 'm', 'i'),
124                        1,
125                        RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
126                        RTEMS_NO_PRIORITY,
127                        &ttyMutex);
128                if (sc != RTEMS_SUCCESSFUL)
129                        rtems_fatal_error_occurred (sc);
130        }
131}
132       
133/*
134 * Open a termios device
135 */
136rtems_status_code
137rtems_termios_open (
138  rtems_device_major_number  major,
139  rtems_device_minor_number  minor,
140  void                      *arg,
141  int                      (*deviceFirstOpen)(int major, int minor, void *arg),
142  int                      (*deviceLastClose)(int major, int minor, void *arg),
143  int                      (*deviceRead)(int minor),
144  int                      (*deviceWrite)(int minor, char *buf, int len)
145  )
146{
147        rtems_status_code sc;
148        rtems_libio_open_close_args_t *args = arg;
149        struct rtems_termios_tty *tty;
150
151        /*
152         * See if the device has already been opened
153         */
154        sc = rtems_semaphore_obtain (ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
155        if (sc != RTEMS_SUCCESSFUL)
156                return sc;
157        for (tty = ttyHead ; tty != NULL ; tty = tty->forw) {
158                if ((tty->major == major) && (tty->minor == minor))
159                        break;
160        }
161        if (tty == NULL) {
162                static char c = 'a';
163
164                /*
165                 * Create a new device
166                 */
167                tty = malloc (sizeof (struct rtems_termios_tty));
168                if (tty == NULL) {
169                        rtems_semaphore_release (ttyMutex);
170                        return RTEMS_NO_MEMORY;
171                }
172                tty->forw = ttyHead;
173                ttyHead = tty;
174                tty->back = NULL;
175                if (ttyTail == NULL)
176                        ttyTail = tty;
177
178                /*
179                 * Set up mutex semaphores
180                 */
181                sc = rtems_semaphore_create (
182                        rtems_build_name ('T', 'R', 'i', c),
183                        1,
184                        RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
185                        RTEMS_NO_PRIORITY,
186                        &tty->isem);
187                if (sc != RTEMS_SUCCESSFUL)
188                        rtems_fatal_error_occurred (sc);
189                sc = rtems_semaphore_create (
190                        rtems_build_name ('T', 'R', 'o', c),
191                        1,
192                        RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
193                        RTEMS_NO_PRIORITY,
194                        &tty->osem);
195                if (sc != RTEMS_SUCCESSFUL)
196                        rtems_fatal_error_occurred (sc);
197
198                /*
199                 * Set callbacks
200                 */
201                tty->write = deviceWrite;
202                tty->lastClose = deviceLastClose;
203                if ((tty->read = deviceRead) == NULL) {
204                        sc = rtems_semaphore_create (
205                                rtems_build_name ('T', 'R', 'r', c),
206                                0,
207                                RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
208                                RTEMS_NO_PRIORITY,
209                                &tty->rawBufSemaphore);
210                        if (sc != RTEMS_SUCCESSFUL)
211                                rtems_fatal_error_occurred (sc);
212                        tty->rawBufHead = 0;
213                        tty->rawBufTail = 0;
214                }
215
216                /*
217                 * Initialize variables
218                 */
219                tty->column = 0;
220                tty->cindex = tty->ccount = 0;
221
222                /*
223                 * Set default parameters
224                 */
225                tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
226                tty->termios.c_oflag = OPOST | ONLCR | XTABS;
227                tty->termios.c_cflag = B9600 | CS8 | CREAD;
228                tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
229                tty->termios.c_cc[VINTR] = '\003';
230                tty->termios.c_cc[VQUIT] = '\034';
231                tty->termios.c_cc[VERASE] = '\177';
232                tty->termios.c_cc[VKILL] = '\025';
233                tty->termios.c_cc[VEOF] = '\004';
234                tty->termios.c_cc[VEOL] = '\000';
235                tty->termios.c_cc[VEOL2] = '\000';
236                tty->termios.c_cc[VSTART] = '\021';
237                tty->termios.c_cc[VSTOP] = '\023';
238                tty->termios.c_cc[VSUSP] = '\032';
239                tty->termios.c_cc[VREPRINT] = '\022';
240                tty->termios.c_cc[VDISCARD] = '\017';
241                tty->termios.c_cc[VWERASE] = '\027';
242                tty->termios.c_cc[VLNEXT] = '\026';
243
244                /*
245                 * Device-specific open
246                 */
247                if (deviceFirstOpen)
248                        (*deviceFirstOpen) (major, minor, arg);
249
250                /*
251                 * Bump name characer
252                 */
253                if (c++ == 'z')
254                        c = 'a';
255        }
256        tty->refcount++;
257        args->iop->data1 = tty;
258        rtems_semaphore_release (ttyMutex);
259        return RTEMS_SUCCESSFUL;
260}
261
262rtems_status_code
263rtems_termios_close (void *arg)
264{
265        rtems_libio_open_close_args_t *args = arg;
266        struct rtems_termios_tty *tty = args->iop->data1;
267        rtems_status_code sc;
268
269        args->ioctl_return = 0;
270        sc = rtems_semaphore_obtain (ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
271        if (sc != RTEMS_SUCCESSFUL)
272                rtems_fatal_error_occurred (sc);
273        if (--tty->refcount == 0) {
274                if (tty->lastClose)
275                         (*tty->lastClose) (tty->major, tty->minor, arg);
276                if (tty->forw == NULL)
277                        ttyTail = tty->back;
278                else
279                        tty->forw->back = tty->back;
280                if (tty->back == NULL)
281                        ttyHead = tty->forw;
282                else
283                        tty->back->forw = tty->forw;
284                rtems_semaphore_delete (tty->isem);
285                rtems_semaphore_delete (tty->osem);
286                if (tty->read == NULL)
287                        rtems_semaphore_delete (tty->rawBufSemaphore);
288                free (tty);
289        }
290        rtems_semaphore_release (ttyMutex);
291        return RTEMS_SUCCESSFUL;
292}
293
294rtems_status_code
295rtems_termios_ioctl (void *arg)
296{
297        rtems_libio_ioctl_args_t *args = arg;
298        struct rtems_termios_tty *tty = args->iop->data1;
299        rtems_status_code sc;
300
301        sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
302        if (sc != RTEMS_SUCCESSFUL)
303                return sc;
304        switch (args->command) {
305        default:
306                sc = RTEMS_INVALID_NUMBER;
307                break;
308
309        case RTEMS_IO_GET_ATTRIBUTES:
310                *(struct termios *)args->buffer = tty->termios;
311                break;
312
313        case RTEMS_IO_SET_ATTRIBUTES:
314                tty->termios = *(struct termios *)args->buffer;
315                if (tty->termios.c_lflag & ICANON) {
316                        tty->rawBufSemaphoreOptions = RTEMS_WAIT;
317                        tty->rawBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
318                        tty->rawBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
319                }
320                else {
321                        rtems_interval ticksPerSecond;
322                        rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond);
323                        tty->vtimeTicks = tty->termios.c_cc[VTIME] * ticksPerSecond / 10;
324                        if (tty->termios.c_cc[VTIME]) {
325                                tty->rawBufSemaphoreOptions = RTEMS_WAIT;
326                                tty->rawBufSemap`oreTimeout = tty->vtimeTicks;
327                                if (tty->termios.c_cc[VMIN])
328                                        tty->rawBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
329                                else
330                                        tty->rawBufSemaphoreFirstTimeout = tty->vtimeTicks;
331                        }
332                        else {
333                                if (tty->termios.c_cc[VMIN]) {
334                                        tty->rawBufSemaphoreOptions = RTEMS_WAIT;
335                                        tty->rawBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
336                                        tty->rawBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
337                                }
338                                else {
339                                        tty->rawBufSemaphoreOptions = RTEMS_NO_WAIT;
340                                }
341                        }
342                }
343                break;
344        }
345        rtems_semaphore_release (tty->osem);
346        return sc;
347}
348
349/*
350 * Handle output processing
351 */
352static void
353oproc (unsigned char c, struct rtems_termios_tty *tty)
354{
355        int     i;
356
357        if (tty->termios.c_oflag & OPOST) {
358                switch (c) {
359                case '\n':
360                        if (tty->termios.c_oflag & ONLRET)
361                                tty->column = 0;
362                        if (tty->termios.c_oflag & ONLCR) {
363                                (*tty->write)(tty->minor, "\r", 1);
364                                tty->column = 0;
365                        }
366                        break;
367
368                case '\r':
369                        if ((tty->termios.c_oflag & ONOCR) && (tty->column == 0))
370                                return;
371                        if (tty->termios.c_oflag & OCRNL) {
372                                c = '\n';
373                                if (tty->termios.c_oflag & ONLRET)
374                                        tty->column = 0;
375                                break;
376                        }
377                        tty->column = 0;
378                        break;
379
380                case '\t':
381                        i = 8 - (tty->column & 7);
382                        if ((tty->termios.c_oflag & TABDLY) == XTABS) {
383                                tty->column += i;
384                                (*tty->write)(tty->minor,  "        ",  i);
385                                return;
386                        }
387                        tty->column += i;
388                        break;
389
390                case '\b':
391                        if (tty->column > 0)
392                                tty->column--;
393                        break;
394
395                default:
396                        if (tty->termios.c_oflag & OLCUC)
397                                c = toupper(c);
398                        if (!iscntrl(c))
399                                tty->column++;
400                        break;
401                }
402        }
403        (*tty->write)(tty->minor, &c, 1);
404}
405
406rtems_status_code
407rtems_termios_write (void *arg)
408{
409        rtems_libio_rw_args_t *args = arg;
410        struct rtems_termios_tty *tty = args->iop->data1;
411        rtems_status_code sc;
412
413        sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
414        if (sc != RTEMS_SUCCESSFUL)
415                return sc;
416        if (tty->termios.c_oflag & OPOST) {
417                unsigned32 count = args->count;
418                unsigned8 *buffer = args->buffer;
419                while (count--)
420                        oproc (*buffer++, tty);
421                args->bytes_moved = args->count;
422        }
423        else {
424                if ((*tty->write)(tty->minor, args->buffer, args->count) < 0)
425                        sc = RTEMS_UNSATISFIED;
426                else
427                        args->bytes_moved = args->count;
428        }
429        rtems_semaphore_release (tty->osem);
430        return sc;
431}
432
433/*
434 * Echo a typed character
435 */
436static void
437echo (unsigned char c, struct rtems_termios_tty *tty)
438{
439        if ((tty->termios.c_lflag & ECHOCTL) && iscntrl(c) && (c != '\t') && (c != '\n')) {
440                char echobuf[2];
441
442                echobuf[0] = '^';
443                echobuf[1] = c ^ 0x40;
444                (*tty->write)(tty->minor, echobuf, 2);
445                tty->column += 2;
446        }
447        else {
448                oproc (c, tty);
449        }
450}
451
452/*
453 * Erase a character or line
454 * FIXME: Needs support for WERASE and ECHOPRT.
455 * FIXME: Some of the tests should check for IEXTEN, too.
456 */
457static void
458erase (struct rtems_termios_tty *tty, int lineFlag)
459{
460        if (tty->ccount == 0)
461                return;
462        if (lineFlag) {
463                if (!(tty->termios.c_lflag & ECHO)) {
464                        tty->ccount = 0;
465                        return;
466                }
467                if (!(tty->termios.c_lflag & ECHOE)) {
468                        tty->ccount = 0;
469                        echo (tty->termios.c_cc[VKILL], tty);
470                        if (tty->termios.c_lflag & ECHOK)
471                                echo ('\n', tty);
472                        return;
473                }
474        }
475        while (tty->ccount) {
476                unsigned char c = tty->cbuf[--tty->ccount];
477
478                if (tty->termios.c_lflag & ECHO) {
479                        if (!lineFlag && !(tty->termios.c_lflag & ECHOE)) {
480                                echo (tty->termios.c_cc[VERASE], tty);
481                        }
482                        else if (c == '\t') {
483                                int col = tty->read_start_column;
484                                int i = 0;
485
486                                /*
487                                 * Find the character before the tab
488                                 */
489                                while (i != tty->ccount) {
490                                        c = tty->cbuf[i++];
491                                        if (c == '\t') {
492                                                col = (col | 7) + 1;
493                                        }
494                                        else if (iscntrl (c)) {
495                                                if (tty->termios.c_lflag & ECHOCTL)
496                                                        col += 2;
497                                        }
498                                        else {
499                                                col++;
500                                        }
501                                }
502
503                                /*
504                                 * Back up over the tab
505                                 */
506                                while (tty->column > col) {
507                                        (*tty->write)(tty->minor, "\b", 1);
508                                        tty->column--;
509                                }
510                        }
511                        else {
512                                if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) {
513                                        (*tty->write)(tty->minor, "\b \b", 3);
514                                        if (tty->column)
515                                                tty->column--;
516                                }
517                                if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) {
518                                        (*tty->write)(tty->minor, "\b \b", 3);
519                                        if (tty->column)
520                                                tty->column--;
521                                }
522                        }
523                }
524                if (!lineFlag)
525                        break;
526        }
527}
528
529/*
530 * Process a single input character
531 */
532static int
533iproc (unsigned char c, struct rtems_termios_tty *tty)
534{
535        if (tty->termios.c_iflag & ISTRIP)
536                c &= 0x7f;
537        if (tty->termios.c_iflag & IUCLC)
538                c = tolower (c);
539        if (c == '\r') {
540                if (tty->termios.c_iflag & IGNCR)
541                        return 0;
542                if (tty->termios.c_iflag & ICRNL)
543                        c = '\n';
544        }
545        else if ((c == '\n') && (tty->termios.c_iflag & INLCR)) {
546                c = '\r';
547        }
548        if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
549                if (c == tty->termios.c_cc[VERASE]) {
550                        erase (tty, 0);
551                        return 0;
552                }
553                else if (c == tty->termios.c_cc[VKILL]) {
554                        erase (tty, 1);
555                        return 0;
556                }
557                else if (c == tty->termios.c_cc[VEOF]) {
558                        return 1;
559                }
560                else if (c == '\n') {
561                        if (tty->termios.c_lflag & (ECHO | ECHONL))
562                                echo (c, tty);
563                        tty->cbuf[tty->ccount++] = c;
564                        return 1;
565                }
566                else if ((c == tty->termios.c_cc[VEOL])
567                      || (c == tty->termios.c_cc[VEOL2])) {
568                        if (tty->termios.c_lflag & ECHO)
569                                echo (c, tty);
570                        tty->cbuf[tty->ccount++] = c;
571                        return 1;
572                }
573        }
574
575        /*
576         * FIXME: Should do IMAXBEL handling somehow
577         */
578        if (tty->ccount < (CBUFSIZE-1)) {
579                if (tty->termios.c_lflag & ECHO)
580                        echo (c, tty);
581                tty->cbuf[tty->ccount++] = c;
582        }
583        return 0;
584}
585
586/*
587 * Process input character, with semaphore.
588 */
589static int
590siproc (unsigned char c, struct rtems_termios_tty *tty)
591{
592        int i;
593
594        /*
595         * Obtain output semaphore if character will be echoed
596         */
597        if (tty->termios.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ECHOPRT|ECHOCTL|ECHOKE)) {
598                rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
599                i = iproc (c, tty);
600                rtems_semaphore_release (tty->osem);
601        }
602        else {
603                i = iproc (c, tty);
604        }
605        return i;
606}
607
608/*
609 * Fill the input buffer by polling the device
610 */
611static rtems_status_code
612fillBufferPoll (struct rtems_termios_tty *tty)
613{
614        int n;
615
616        if (tty->termios.c_lflag & ICANON) {
617                for (;;) {
618                        n = (*tty->read)(tty->minor);
619                        if (n < 0) {
620                                rtems_task_wake_after (1);
621                        }
622                        else {
623                                if  (siproc (n, tty))
624                                        break;
625                        }
626                }
627        }
628        else {
629                rtems_interval then, now;
630                if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
631                        rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
632                for (;;) {
633                        n = (*tty->read)(tty->minor);
634                        if (n < 0) {
635                                if (tty->termios.c_cc[VMIN]) {
636                                        if (tty->termios.c_cc[VTIME] && tty->ccount) {
637                                                rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
638                                                if ((now - then) > tty->vtimeTicks) {
639                                                        break;
640                                                }
641                                        }
642                                }
643                                else {
644                                        if (!tty->termios.c_cc[VTIME])
645                                                break;
646                                        rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
647                                        if ((now - then) > tty->vtimeTicks) {
648                                                break;
649                                        }
650                                }
651                                rtems_task_wake_after (1);
652                        }
653                        else {
654                                siproc (n, tty);
655                                if (tty->ccount >= tty->termios.c_cc[VMIN])
656                                        break;
657                                if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
658                                        rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
659                        }
660                }
661        }
662        return RTEMS_SUCCESSFUL;
663}
664
665/*
666 * Fill the input buffer from the raw input queue
667 */
668static rtems_status_code
669fillBufferQueue (struct rtems_termios_tty *tty)
670{
671        rtems_interval timeout = tty->rawBufSemaphoreFirstTimeout;
672        rtems_status_code sc;
673
674        for (;;) {
675                /*
676                 * Process characters read from raw queue
677                 */
678                while (tty->rawBufHead != tty->rawBufTail) {
679                        unsigned char c;
680                        unsigned int newHead;
681
682                        newHead = (tty->rawBufHead + 1) % RAW_BUFFER_SIZE;
683                        c = tty->rawBuf[newHead];
684                        tty->rawBufHead = newHead;
685                        if (tty->termios.c_lflag & ICANON) {
686                                if  (siproc (c, tty))
687                                        return RTEMS_SUCCESSFUL;
688                        }
689                        else {
690                                siproc (c, tty);
691                                if (tty->ccount >= tty->termios.c_cc[VMIN])
692                                        return RTEMS_SUCCESSFUL;
693                        }
694                        timeout = tty->rawBufSemaphoreTimeout;
695                }
696
697                /*
698                 * Wait for characters
699                 */
700                sc = rtems_semaphore_obtain (tty->rawBufSemaphore,
701                                                tty->rawBufSemaphoreOptions,
702                                                timeout);
703                if (sc != RTEMS_SUCCESSFUL)
704                        break;
705        }
706        return RTEMS_SUCCESSFUL;
707}
708
709rtems_status_code
710rtems_termios_read (void *arg)
711{
712        rtems_libio_rw_args_t *args = arg;
713        struct rtems_termios_tty *tty = args->iop->data1;
714        unsigned32 count = args->count;
715        unsigned8 *buffer = args->buffer;
716        rtems_status_code sc;
717
718        sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
719        if (sc != RTEMS_SUCCESSFUL)
720                return sc;
721        if (tty->cindex == tty->ccount) {
722                tty->cindex = tty->ccount = 0;
723                tty->read_start_column = tty->column;
724                if (tty->read)
725                        sc = fillBufferPoll (tty);
726                else
727                        sc = fillBufferQueue (tty);
728                if (sc != RTEMS_SUCCESSFUL)
729                        tty->cindex = tty->ccount = 0;
730        }
731        while (count && (tty->cindex < tty->ccount)) {
732                *buffer++ = tty->cbuf[tty->cindex++];
733                count--;
734        }
735        args->bytes_moved = args->count - count;
736        rtems_semaphore_release (tty->isem);
737        return sc;
738}
739
740/*
741 * Place characters on raw queue.
742 * NOTE: This routine runs in the context of the device interrupt handler.
743 */
744void
745rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
746{
747        struct rtems_termios_tty *tty = ttyp;
748        unsigned int newTail;
749
750        while (len) {
751                newTail = (tty->rawBufTail + 1) % RAW_BUFFER_SIZE;
752                if (newTail == tty->rawBufHead) {
753                        tty->rawBufDropped += len;
754                        break;
755                }
756                tty->rawBuf[newTail] = *buf++;
757                len--;
758                tty->rawBufTail = newTail;
759        }
760        rtems_semaphore_release (tty->rawBufSemaphore);
761}
762
763/*
764 *  Reserve enough resources to open every physical device once.
765 */
766
767void rtems_termios_reserve_resources(
768  rtems_configuration_table *configuration,
769  rtems_unsigned32           number_of_devices
770)
771{
772  static int first_time = 1;
773  rtems_api_configuration_table *rtems_config;
774
775  if (!configuration)
776    rtems_fatal_error_occurred (0xFFF0F001);
777
778  rtems_config = configuration->RTEMS_api_configuration;
779  if (!rtems_config)
780    rtems_fatal_error_occurred (0xFFF0F002);
781
782  if (first_time)
783    rtems_config->maximum_semaphores += 1;
784
785  first_time = 0;
786  rtems_config->maximum_semaphores += (3 * number_of_devices);
787}
Note: See TracBrowser for help on using the repository browser.