source: rtems/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c @ 9deb5b8b

4.104.114.84.95
Last change on this file since 9deb5b8b was 9deb5b8b, checked in by Joel Sherrill <joel.sherrill@…>, on 08/01/97 at 18:12:11

Katsutoshi Shibuya (shibuya@…)of BU-Denken Co., Ltd.
(Sapporo, Japan) submitted the extended console driver for the
MVME162LX BSP and the POSIX tcsetattr() and tcgetattr() routines.
This device driver supports four serial ports, cooked IO, and
provides a portable base for Zilog 8530 based console drivers.

  • Property mode set to 100644
File size: 18.5 KB
Line 
1/*
2 *  This file contains the MVME162LX extended console IO package.
3 *
4 *  This file was created originally by
5 *  On-Line Applications Research Corporation (OAR)
6 *  and modified by:
7 *
8 *  Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
9 *
10 *  featuring support of:
11 *
12 *     - Multi-SCC chip handling
13 *     - Non-blocking I/O (O_NDELAY flag in libc)
14 *     - Raw mode device (no CR/LF detection)
15 *     - RTS/CTS flow control
16 *
17 *  REMARKS: This routine requires multiple interrupt vectors
18 *           from SCC_VECTOR (normaly 0x40)
19 *           to SCC_VECTOR+(number of SCC chips)
20 *
21 *  The original copyright follows;
22 *
23 *  COPYRIGHT (c) 1989-1997.
24 *  On-Line Applications Research Corporation (OAR).
25 *  Copyright assigned to U.S. Government, 1994.
26 *
27 *  The license and distribution terms for this file may in
28 *  the file LICENSE in this distribution or at
29 *  http://www.OARcorp.com/rtems/license.html.
30 *
31 *  Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
32 *  EISCAT Scientific Association. M.Savitski
33 *
34 *  This material is a part of the MVME162 Board Support Package
35 *  for the RTEMS executive. Its licensing policies are those of the
36 *  RTEMS above.
37 *
38 */
39
40#define M162_INIT
41
42#include "consolex.h"
43#include <bsp.h>
44#include <rtems/libio.h>
45#include <stdio.h>
46#include <string.h>
47#include <ctype.h>
48
49#define NPORTS  4       /* Number of ports */
50#define DEVICEPREFIX    "tty"
51#define RAWDEVICEPREFIX "rtty"
52#define CONSOLEPORT 0   /* port# of console:
53                           undef this if you do not want /dev/console */
54#define READRETRY 1     /* Maximum retry count for read one char */
55#define WRITERETRY 8    /* Maximum retry count for write one char */
56
57#define PORTFROM 0      /* for debug */
58
59static unsigned char    opencount[NPORTS];
60
61/***********************************************************************
62   Ring buffer for device
63 ***********************************************************************/
64
65#define QUEUE_LENGTH 128        /* Must be 2^n number */
66
67typedef struct {
68  char buffer[QUEUE_LENGTH];
69  volatile int  head;
70  volatile int  tail;
71} ReceiverBuffer;
72
73#define ReceiverBufferInitialize( _buffer ) \
74  do { \
75    (_buffer)->head = (_buffer)->tail = 0; \
76  } while ( 0 )
77 
78#define ReceiverBufferIsEmpty( _buffer ) \
79   ( (_buffer)->tail == (_buffer)->head )
80
81#define ReceiverBufferIsNearEmpty( _buffer ) \
82   ( (_buffer)->tail == (((_buffer)->head + 3) & (QUEUE_LENGTH-1)) )
83
84#define ReceiverBufferIsFull( _buffer ) \
85   ( (_buffer)->head == (((_buffer)->tail + 1) & (QUEUE_LENGTH-1)) )
86
87#define ReceiverBufferIsNearFull( _buffer ) \
88   ( (_buffer)->head == (((_buffer)->tail + 3) & (QUEUE_LENGTH-1)) )
89
90#define ReceiverBufferAdd( _buffer, _ch ) \
91  do { \
92    rtems_unsigned32 isrlevel; \
93    \
94    rtems_interrupt_disable( isrlevel ); \
95      (_buffer)->tail = ((_buffer)->tail+1) & (QUEUE_LENGTH-1); \
96      (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
97    rtems_interrupt_enable( isrlevel ); \
98  } while ( 0 )
99
100#define ReceiverBufferRemove( _buffer, _ch ) \
101  do { \
102    rtems_unsigned32 isrlevel; \
103    \
104    rtems_interrupt_disable( isrlevel ); \
105      (_buffer)->head = ((_buffer)->head+1) & (QUEUE_LENGTH-1); \
106      (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
107    rtems_interrupt_enable( isrlevel ); \
108  } while ( 0 )
109
110
111/***********************************************************************
112   DEVICE DEPENDED PART
113 ***********************************************************************/
114
115
116/* Time constant parameters
117   CAUTION: These parameters are for MVME162LX-213 board.
118 */
119
120#define TC38400 0x0006
121#define TC19200 0x000e
122#define TC9600  0x001e
123
124/* Re-defining SCC register control macros
125   to support Multi SCC chips */
126
127#undef  scc
128static scc_regs *scc[NPORTS] = {
129    ((scc_regs * const) 0xFFF45004),
130    ((scc_regs * const) 0xFFF45000),
131    ((scc_regs * const) 0xFFF45804),
132    ((scc_regs * const) 0xFFF45800)
133};
134
135#undef  ZWRITE0
136#define ZWRITE0(port, v)  (scc[port]->csr = (unsigned char)(v))
137#undef  ZREAD0
138#define ZREAD0(port)  (scc[port]->csr)
139
140#undef  ZREAD
141#define ZREAD(port, n)  (ZWRITE0(port, n), (scc[port]->csr))
142#undef  ZREADD
143#define ZREADD(port)  (scc[port]->csr=0x08, scc[port]->csr )
144
145#undef  ZWRITE
146#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))
147#undef  ZWRITED
148#define ZWRITED(port, v)  (scc[port]->csr = 0x08, \
149                           scc[port]->csr = (unsigned char)(v))
150
151static ReceiverBuffer   receiverBuffer[NPORTS];
152
153/*
154 *  Control flags (DTR/DCD/RTS/CTS)
155 */
156
157static unsigned char    wr4[NPORTS];
158static unsigned char    wr5[NPORTS];
159#define SCCSetDTR(port) ZWRITE(port, 5, (wr5[port] |= 0x80))
160#define SCCResetDTR(port) ZWRITE(port, 5, (wr5[port] &= ~0x80))
161#define SCCSetRTS(port) ZWRITE(port, 5, (wr5[port] |= 0x02))
162#define SCCResetRTS(port) ZWRITE(port,5, (wr5[port] &= ~0x02))
163#define SCCGetDCD(port) (ZREAD0(port)&0x08)
164#define SCCGetCTS(port) (ZREAD0(port)&0x20)
165
166
167/*
168 *  Interrupt handler for receiver interrupts
169 */
170
171static rtems_isr        SCCReceiverISR(rtems_vector_number vector)
172{
173    register int    ipend, port;
174
175    port = (vector-SCC_VECTOR)*2;
176    ZWRITE0(port, 0x38);        /* reset highest IUS */
177
178    ipend = ZREAD(port, 3);     /* read int pending from A side */
179
180    if(ipend == 0x04)
181        port++; /* channel B intr pending */
182    else if(ipend == 0x20)
183        ;       /* channel A intr pending */
184    else
185        return;
186   
187    ReceiverBufferAdd(&receiverBuffer[port], ZREADD(port));
188   
189    if(ZREAD(port,1) & 0x70){ /* check error stat */
190        ZWRITE0(port, 0x30);    /* reset error */
191    }
192
193    if(ReceiverBufferIsNearFull(&receiverBuffer[port]))
194        SCCResetRTS(port);
195}
196
197/*
198 * Initialize
199 */
200
201void    SCCInitialize()
202{
203    int     i;
204
205    for(i = PORTFROM; i < NPORTS; i+=2)
206        ZWRITE(i, 9,0xc0);      /* Reset SCC Chip */
207   
208    for(i = PORTFROM; i < NPORTS; i++){
209        ReceiverBufferInitialize(&(receiverBuffer[i]));
210        wr4[i] = 0x44;
211        ZWRITE(i, 4, wr4[i]);   /* x16 clock, 1 stop, parity none */
212        ZWRITE(i, 1, 0);        /* disable interrupts */
213        ZWRITE(i, 2, SCC_VECTOR+(i/2));
214        ZWRITE(i, 3, 0xc1);     /* receiver enable, 8bits */
215        wr5[i] = 0x68;
216        ZWRITE(i, 5, wr5[i]);   /* transmitter enable, 8bits, DTR&RTS off */
217        ZWRITE(i,14, 0);        /* stop baudrate gen. */
218        ZWRITE(i,11,0x50);      /* use baurate gen. */
219        ZWRITE(i,15, 1);        /* Select WR7' */
220        ZWRITE(i, 7, 0);        /* Disable all special interrupts */
221        ZWRITE(i,10, 0);
222        ZWRITE(i, 1, 0x10);     /* int on all Rx chars or special condition */
223        set_vector(SCCReceiverISR, SCC_VECTOR+(i/2), 1); /* install ISR */
224        ZWRITE(i, 9, 8);        /* master interrupt enable */
225        ZWRITE(i,12,TC38400&0xff);      /* set 38400 baud */
226        ZWRITE(i,13,TC38400>>8);
227        ZWRITE(i,14, 3);        /* start baudrate gen. */
228                                /* CAUTION: If your SCC use XTAL on RTxC,
229                                   write 1 */
230    }
231    mcchip->vector_base = 0;
232    mcchip->gen_control = 2;    /* MIEN */
233    mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */
234}
235
236/*
237 *   Non-blocking char input
238 */
239
240rtems_boolean   SCCGetOne(int port, char *ch)
241{
242    int retry = READRETRY;
243    while(ReceiverBufferIsEmpty(&receiverBuffer[port]))
244        if(--retry <= 0)
245            return FALSE;
246
247    ReceiverBufferRemove(&receiverBuffer[port],*ch);
248
249    if(ReceiverBufferIsNearEmpty(&receiverBuffer[port]))
250        SCCSetRTS(port);
251    return TRUE;
252}
253
254/*
255 *   Blocking char input
256 */
257
258char    SCCGetOneBlocked(int port)
259{
260    unsigned char tmp_char;
261 
262    while (!SCCGetOne(port, &tmp_char))
263        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
264    return tmp_char;
265}
266
267/*
268 *   Non-blocking char input
269 *   No longer supports XON/XOFF flow control.
270 */
271
272rtems_boolean   SCCSendOne(int port, char ch)
273{
274    int retry = WRITERETRY;
275
276    if(!SCCGetCTS(port))
277        return FALSE;
278    while(!(ZREAD0(port) & TX_BUFFER_EMPTY))
279        if(--retry <= 0)
280            return FALSE;
281    ZWRITED(port, ch);
282    return TRUE;
283}
284
285
286/* 
287 *   Blocking char output
288 *   No longer supports XON/XOFF flow control.
289 */
290
291void    SCCSendOneBlocked(int port, char ch)
292{
293    while(!SCCSendOne(port, ch))
294        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
295}
296
297/*
298 * Set parameters for transmission
299 */
300
301unsigned32      SCCSetAttributes(int port, struct termios *t)
302{
303    unsigned char       wr3;
304   
305    ZWRITE(port,1,0);   /* Disable interrupt */
306    ZWRITE(port,3,0);   /* Disable receiver */
307    /* Baud */
308    switch(t->c_cflag & CBAUD){
309    case B38400:
310        ZWRITE(port,12,TC38400&0xff);
311        ZWRITE(port,13,TC38400>>8);
312        break;
313    case B19200:
314        ZWRITE(port,12,TC19200&0xff);
315        ZWRITE(port,13,TC19200>>8);
316        break;
317    case B9600:
318        ZWRITE(port,12,TC9600&0xff);
319        ZWRITE(port,13,TC9600>>8);
320        break;
321    }
322   
323    /* Code size */
324    wr5[port] &= 0x8f;
325    wr3 = 0;    /* receiver control */
326    switch(t->c_cflag & CSIZE){
327    case CS8:
328        wr5[port] |= 0x60;
329        wr3 |= 0xc0;
330        break;
331    case CS7:
332        wr5[port] |= 0x20;
333        wr3 |= 0x40;
334        break;
335    }
336
337    /* Parity */
338    wr4[port] &= 0xf0;
339    if(t->c_cflag & PARENB)
340        wr4[port] |= 0x01;
341    if(!(t->c_cflag & PARODD))
342        wr4[port] |= 0x02;
343    /* ZWRITE(port,4,wr4[port]);*/
344
345    /* Stop bits */
346    /* wr4[port] = ZREAD(port,4) & 0xfc;*/
347    if(t->c_cflag & CSTOPB)
348        wr4[port] |= 0x0c;
349    else
350        wr4[port] |= 0x04;
351   
352    ZWRITE(port,4,wr4[port]);   /* TxRx parameters */
353    ZWRITE(port,5,wr5[port]);   /* Transmission parameters */
354    ZWRITE(port,3,wr3|0x01);    /* Enable receiver */
355    ZWRITE(port,1,0x10);        /* Enable interrupt */
356
357    return 0;
358}
359
360/*
361 * Get parameters for transmission
362 */
363
364unsigned32      SCCGetAttributes(int port, struct termios *t)
365{
366    unsigned32  b;
367
368    t->c_cflag = 0;
369   
370    /* Baud */
371    b = ZREAD(port,13);
372    b <<= 8;
373    b |= ZREAD(port,12);
374    switch(b){
375    case TC38400:
376        t->c_cflag |= B38400;
377        break;
378    case TC19200:
379        t->c_cflag |= B19200;
380        break;
381    case TC9600:
382        t->c_cflag |= B9600;
383        break;
384    }
385   
386    /* Code size */
387    /* wr = ZREAD(port,5);*/
388    t->c_cflag &= ~CSIZE;
389    switch(wr5[port]&0x60){
390    case 0x60:
391        t->c_cflag |= CS8;
392        break;
393    case 0x20:
394        t->c_cflag |= CS7;
395        break;
396    }
397
398    /* Parity */
399    /* wr = ZREAD(port,4);*/
400    if(wr4[port] & 0x01)
401        t->c_cflag |= PARENB;
402    else
403        t->c_cflag &= ~PARENB;
404    if(wr4[port] & 0x02)
405        t->c_cflag &= ~PARODD;
406    else
407        t->c_cflag |= PARODD;
408
409    /* Stop bits */
410    /* wr = ZREAD(port,4);*/
411    if((wr4[port]&0xc0) == 0xc0)
412        t->c_cflag |= CSTOPB;
413    else
414        t->c_cflag &= ~CSTOPB;
415
416    return 0;
417}
418
419/***********************************************************************
420   DEVICE INDEPENDED PART
421 ***********************************************************************/
422
423#define LOCAL_ISTRIP    0x0001
424#define LOCAL_INLCR     0x0002
425#define LOCAL_IGNCR     0x0004
426#define LOCAL_ICRNL     0x0008
427#define LOCAL_IUCLC     0x0010
428#define LOCAL_OLCUC     0x0020
429#define LOCAL_ONLCR     0x0040
430#define LOCAL_OCRNL     0x0080
431#define LOCAL_ICANON    0x0100
432#define LOCAL_ECHO      0x0200
433
434/*
435 *  Device initialize entry point
436 */
437
438rtems_device_driver consolex_initialize(rtems_device_major_number  major,
439                                        rtems_device_minor_number  minor,
440                                        void *arg)
441{
442    rtems_status_code   status;
443    char        devname[16];
444    int         i;
445   
446    SCCInitialize();
447
448#ifdef  CONSOLEPORT
449    status = rtems_io_register_name("/dev/console",major,
450                                    (rtems_device_minor_number) CONSOLEPORT);
451    if (status != RTEMS_SUCCESSFUL)
452        rtems_fatal_error_occurred(status);
453#endif
454   
455    for(i = PORTFROM; i < NPORTS; i++){
456        /* Register cooked ttys */
457        sprintf(devname,"/dev/%s%02d",DEVICEPREFIX,i);
458        status = rtems_io_register_name(strdup(devname),major,
459                                        (rtems_device_minor_number) i);
460        if (status != RTEMS_SUCCESSFUL)
461            rtems_fatal_error_occurred(status);
462        /* Register raw ttys */
463        sprintf(devname,"/dev/%s%02d",RAWDEVICEPREFIX,i);
464        status = rtems_io_register_name(strdup(devname),major,
465                                        (rtems_device_minor_number) i+NPORTS);
466        if (status != RTEMS_SUCCESSFUL)
467            rtems_fatal_error_occurred(status);
468    }
469
470    for(i = 0; i < NPORTS; i++){
471        opencount[i] = 0;
472    }
473   
474    return RTEMS_SUCCESSFUL;
475}
476
477/*
478 *  Open entry point
479 */
480
481rtems_device_driver consolex_open(rtems_device_major_number major,
482                                  rtems_device_minor_number minor,
483                                  void *arg)
484{
485    rtems_libio_open_close_args_t *openargs = (rtems_libio_open_close_args_t *) arg;
486    if(minor >= NPORTS)
487        minor -= NPORTS;
488    if(minor >= NPORTS)
489        return RTEMS_INVALID_NUMBER;
490
491    if(opencount[minor]++ == 0){
492        /* first open */
493        SCCSetDTR(minor);
494        SCCSetRTS(minor);
495    }
496    openargs->iop->data0 = LOCAL_ICRNL|LOCAL_ONLCR|LOCAL_ICANON|LOCAL_ECHO;
497    return RTEMS_SUCCESSFUL;
498}
499
500/*
501 *  Close entry point
502 */
503
504rtems_device_driver consolex_close(rtems_device_major_number major,
505                                   rtems_device_minor_number minor,
506                                   void *arg)
507{
508    if(minor >= NPORTS)
509        minor -= NPORTS;
510    if(minor >= NPORTS)
511        return RTEMS_INVALID_NUMBER;
512
513    if(--(opencount[minor]) == 0){
514        /* closed all */
515        SCCResetRTS(minor);
516        SCCResetDTR(minor);
517    }
518    return RTEMS_SUCCESSFUL;
519}
520
521/*
522 * read bytes from the serial port.
523 */
524
525rtems_device_driver consolex_read_raw(rtems_device_major_number major,
526                                      rtems_device_minor_number minor,
527                                      void *arg)
528{
529    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
530    char *buffer;
531    int count;
532
533    if(minor >= NPORTS)
534        return RTEMS_INVALID_NUMBER;
535
536    buffer = rw_args->buffer;
537    count = rw_args->count;
538
539    if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
540        /* Non blocking read */
541        while(count){
542            if(!SCCGetOne(minor,buffer))
543                break;
544            buffer++;
545            count--;
546        }
547    }else{
548        /* Blocking read */
549        while(count){
550            *buffer = SCCGetOneBlocked(minor);
551            buffer++;
552            count--;
553        }
554    }
555
556    rw_args->bytes_moved = rw_args->count-count;
557    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
558}
559
560rtems_device_driver consolex_read(rtems_device_major_number major,
561                                      rtems_device_minor_number minor,
562                                      void *arg)
563{
564    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
565    char *buffer;
566    int count;
567    unsigned32  mode;
568
569    if(minor >= NPORTS)
570        return consolex_read_raw(major,minor-NPORTS,arg);
571
572    buffer = rw_args->buffer;
573    count = rw_args->count;
574    mode = rw_args->iop->data0;
575   
576    /* Cooked read */
577    while(count){
578        if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
579            /* Non blocking read */
580            if(!SCCGetOne(minor,buffer))
581                break;
582        }else{
583            /* Blocking read */
584            *buffer = SCCGetOneBlocked(minor);
585        }
586        if((mode&LOCAL_ICANON) && (*buffer == '\b')){
587            if(buffer > (char *)(rw_args->buffer)){
588                buffer--;
589                count++;
590                if(mode&LOCAL_ECHO){
591                    SCCSendOneBlocked(minor,'\b');
592                    SCCSendOneBlocked(minor,' ');
593                    SCCSendOneBlocked(minor,'\b');
594                }
595            }
596            continue;
597        }
598        if((mode&LOCAL_IGNCR) && (*buffer == '\r'))
599            continue;
600        if((mode&LOCAL_INLCR) && (*buffer == '\n'))
601            *buffer = '\r';
602        if((mode&LOCAL_ICRNL) && (*buffer == '\r'))
603            *buffer = '\n';
604        if((mode&LOCAL_IUCLC) && isupper(*buffer))
605            *buffer = tolower(*buffer);
606        if(mode&LOCAL_ISTRIP)
607            *buffer &= 0x7f;
608        if(mode&LOCAL_ECHO){
609            /* Caution: Echo back is blocking output */
610            SCCSendOneBlocked(minor,*buffer);
611        }
612        if((mode&LOCAL_ICANON) && (*buffer == '\n')){
613            buffer++;
614            count--;
615            if(count)
616                *buffer = 0;
617            if((mode&LOCAL_ECHO)&&(mode&LOCAL_ONLCR))
618                SCCSendOneBlocked(minor,'\r');
619            break;      /* finish reading */
620        }
621        buffer++;
622        count--;
623    }
624    rw_args->bytes_moved = rw_args->count-count;
625    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
626}
627
628/*
629 * write bytes to the serial port.
630 */
631
632rtems_device_driver consolex_write_raw(rtems_device_major_number major,
633                                       rtems_device_minor_number minor,
634                                       void * arg)
635{
636    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
637    char *buffer;
638    int count;
639
640    if(minor >= NPORTS)
641        return RTEMS_INVALID_NUMBER;
642
643    buffer = rw_args->buffer;
644    count = rw_args->count;
645
646    if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
647        /* Non blocking write */
648        while(count){
649            if(!SCCSendOne(minor,*buffer))
650                break;
651            buffer++;
652            count--;
653        }
654    }else{
655        /* Blocking write */
656        while(count){
657            SCCSendOneBlocked(minor,*buffer);
658            buffer++;
659            count--;
660        }
661    }
662   
663    rw_args->bytes_moved = rw_args->count-count;
664    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
665}
666
667rtems_device_driver consolex_write(rtems_device_major_number major,
668                                   rtems_device_minor_number minor,
669                                   void * arg)
670{
671    rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
672    char *buffer;
673    int count;
674    char        ch;
675    unsigned32  mode;
676
677    if(minor >= NPORTS)
678        return consolex_write_raw(major,minor-NPORTS,arg);
679
680    buffer = rw_args->buffer;
681    count = rw_args->count;
682    mode = rw_args->iop->data0;
683
684    /* Cooked write */
685    while(count){
686        ch = *buffer;
687        if((mode&LOCAL_ONLCR) && (ch == '\n')){ /* Output CRLF */
688            if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
689                /* Non blocking write */
690                if(!SCCSendOne(minor,'\r'))
691                    break;
692            }else{
693                SCCSendOneBlocked(minor,'\r');
694            }
695        }
696        if((mode&LOCAL_OCRNL) && (ch == '\r'))
697            ch = '\n';
698        if((mode&OLCUC) && (islower(ch)))
699            ch = toupper(ch);
700        if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
701            /* Non blocking write */
702            if(!SCCSendOne(minor,ch))
703                break;
704        }else{
705            SCCSendOneBlocked(minor,ch);
706        }
707        buffer++;
708        count--;
709    }
710   
711    rw_args->bytes_moved = rw_args->count-count;
712    return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
713}
714
715/*
716 *  IO Control entry point
717 */
718
719rtems_device_driver consolex_control(rtems_device_major_number major,
720                                     rtems_device_minor_number minor,
721                                     void * arg)
722{
723    rtems_libio_ioctl_args_t    *ioarg = (rtems_libio_ioctl_args_t *)arg;
724    struct termios      *tm = ioarg->buffer;
725    unsigned32  *mode = &(ioarg->iop->data0);
726
727    if(minor >= NPORTS)
728        minor -= NPORTS;
729    if(minor >= NPORTS)
730        return RTEMS_INVALID_NUMBER;
731
732    switch(ioarg->command){
733    case RTEMS_IO_GET_ATTRIBUTES:
734        tm->c_iflag = tm->c_oflag = tm->c_cflag = tm->c_lflag = 0;
735        if(*mode & LOCAL_ISTRIP)
736            tm->c_iflag |= ISTRIP;
737        if(*mode & LOCAL_INLCR)
738            tm->c_iflag |= INLCR;
739        if(*mode & LOCAL_IGNCR)
740            tm->c_iflag |= IGNCR;
741        if(*mode & LOCAL_ICRNL)
742            tm->c_iflag |= ICRNL;
743        if(*mode & LOCAL_IUCLC)
744            tm->c_iflag |= IUCLC;
745        if(*mode & LOCAL_OLCUC)
746            tm->c_oflag |= OLCUC;
747        if(*mode & LOCAL_ONLCR)
748            tm->c_oflag |= ONLCR;
749        if(*mode & LOCAL_OCRNL)
750            tm->c_oflag |= OCRNL;
751        if(*mode & LOCAL_ICANON)
752            tm->c_lflag |= ICANON;
753        if(*mode & LOCAL_ECHO)
754            tm->c_lflag |= ECHO;
755        ioarg->ioctl_return = SCCGetAttributes(minor,tm);
756        break;
757    case RTEMS_IO_SET_ATTRIBUTES:
758        *mode = 0;
759        if(tm->c_iflag & ISTRIP)
760            *mode |= LOCAL_ISTRIP;
761        if(tm->c_iflag & INLCR)
762            *mode |= LOCAL_INLCR;
763        if(tm->c_iflag & IGNCR)
764            *mode |= LOCAL_IGNCR;
765        if(tm->c_iflag & ICRNL)
766            *mode |= LOCAL_ICRNL;
767        if(tm->c_iflag & IUCLC)
768            *mode |= LOCAL_IUCLC;
769        if(tm->c_oflag & OLCUC)
770            *mode |= LOCAL_OLCUC;
771        if(tm->c_oflag & ONLCR)
772            *mode |= LOCAL_ONLCR;
773        if(tm->c_oflag & OCRNL)
774            *mode |= LOCAL_OCRNL;
775        if(tm->c_lflag & ICANON)
776            *mode |= LOCAL_ICANON;
777        if(tm->c_lflag & ECHO)
778            *mode |= LOCAL_ECHO;
779        ioarg->ioctl_return = SCCSetAttributes(minor,tm);
780        break;
781    default:
782        return RTEMS_NOT_DEFINED;
783    }
784   
785    return RTEMS_SUCCESSFUL;
786}
Note: See TracBrowser for help on using the repository browser.