summaryrefslogtreecommitdiffstats
path: root/c/src
diff options
context:
space:
mode:
Diffstat (limited to 'c/src')
-rw-r--r--c/src/exec/libcsupport/include/rtems/libio.h7
-rw-r--r--c/src/exec/libcsupport/include/sys/termios.h184
-rw-r--r--c/src/lib/include/Makefile.in7
-rw-r--r--c/src/lib/include/rtems/libio.h7
-rw-r--r--c/src/lib/include/sys/termios.h184
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/Makefile.in12
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/README29
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in54
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/README97
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c75
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c786
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h93
-rw-r--r--c/src/lib/libc/Makefile.in2
-rw-r--r--c/src/lib/libc/libio.h7
-rw-r--r--c/src/lib/libc/newlibif.c30
-rw-r--r--c/src/lib/libc/tcattr.c40
16 files changed, 1603 insertions, 11 deletions
diff --git a/c/src/exec/libcsupport/include/rtems/libio.h b/c/src/exec/libcsupport/include/rtems/libio.h
index c79dfc2e33..d77480e4af 100644
--- a/c/src/exec/libcsupport/include/rtems/libio.h
+++ b/c/src/exec/libcsupport/include/rtems/libio.h
@@ -121,4 +121,11 @@ void rtems_register_libio_handler(int handler_flag,
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
+/*
+ * IOCTL values
+ */
+
+#define RTEMS_IO_GET_ATTRIBUTES 1
+#define RTEMS_IO_SET_ATTRIBUTES 2
+
#endif /* _RTEMS_LIBIO_H */
diff --git a/c/src/exec/libcsupport/include/sys/termios.h b/c/src/exec/libcsupport/include/sys/termios.h
new file mode 100644
index 0000000000..d64d57b8c3
--- /dev/null
+++ b/c/src/exec/libcsupport/include/sys/termios.h
@@ -0,0 +1,184 @@
+/*
+ * POSIX termios implementation for RTEMS console device driver.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef TERMIOS_H
+#define TERMIOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+/* Currently we support only tcgetattr and tcsetattr */
+int tcgetattr(int, struct termios *);
+int tcsetattr(int, int, struct termios *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TERMIOS_H */
diff --git a/c/src/lib/include/Makefile.in b/c/src/lib/include/Makefile.in
index fb1cb2c67f..bb35475c02 100644
--- a/c/src/lib/include/Makefile.in
+++ b/c/src/lib/include/Makefile.in
@@ -11,6 +11,9 @@ H_PIECES=console clockdrv iosupp ringbuf \
spurious timerdrv vmeintr z8036 z8530 z8536
H_FILES=$(H_PIECES:%=$(srcdir)/%.h)
+SYS_H_PIECES=termios
+SYS_H_FILES=$(SYS_H_PIECES:%=$(srcdir)/sys/%.h)
+
KA9Q_H_PIECES= arp asy ax25 ax25mail bootp cmdparse commands config \
daemon dialer domain enet ftp ftpcli global hardware icmp iface \
internet ip kiss lapb lzw mailbox mbuf netuser nospc nr4 nr4mail \
@@ -22,9 +25,7 @@ RTEMSCPLUSPLUS_H_PIECES= rtemsEvent rtemsInterrupt rtemsMessageQueue \
rtemsSemaphore rtemsStatusCode rtemsTask rtemsTaskMode rtemsTimer
RTEMSCPLUSPLUS_H_FILES=$(RTEMSCPLUSPLUS_H_PIECES:%=$(srcdir)/rtems++/%.h)
-SYS_H_FILES=
-
-SRCS=$(H_FILES) $(SYS_H_FILES)
+SRCS=$(H_FILES) $(SYS_H_FILES) $(KA9Q_H_FILES) $(RTEMSCPLUSPLUS_H_FILES)
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
diff --git a/c/src/lib/include/rtems/libio.h b/c/src/lib/include/rtems/libio.h
index c79dfc2e33..d77480e4af 100644
--- a/c/src/lib/include/rtems/libio.h
+++ b/c/src/lib/include/rtems/libio.h
@@ -121,4 +121,11 @@ void rtems_register_libio_handler(int handler_flag,
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
+/*
+ * IOCTL values
+ */
+
+#define RTEMS_IO_GET_ATTRIBUTES 1
+#define RTEMS_IO_SET_ATTRIBUTES 2
+
#endif /* _RTEMS_LIBIO_H */
diff --git a/c/src/lib/include/sys/termios.h b/c/src/lib/include/sys/termios.h
new file mode 100644
index 0000000000..d64d57b8c3
--- /dev/null
+++ b/c/src/lib/include/sys/termios.h
@@ -0,0 +1,184 @@
+/*
+ * POSIX termios implementation for RTEMS console device driver.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef TERMIOS_H
+#define TERMIOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+/* Currently we support only tcgetattr and tcsetattr */
+int tcgetattr(int, struct termios *);
+int tcsetattr(int, int, struct termios *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TERMIOS_H */
diff --git a/c/src/lib/libbsp/m68k/mvme162/Makefile.in b/c/src/lib/libbsp/m68k/mvme162/Makefile.in
index c72d071f77..68ce414233 100644
--- a/c/src/lib/libbsp/m68k/mvme162/Makefile.in
+++ b/c/src/lib/libbsp/m68k/mvme162/Makefile.in
@@ -12,8 +12,18 @@ include $(PROJECT_ROOT)/make/directory.cfg
SRCS=README
+# If the MVME162 is an LX model, then there are 2 z8530's to yield
+# four serial ports. The application can choose this driver by
+# using "CONSOLEX_DRIVER_TABLE_ENTRY" in the driver table definition,
+# in place of "CONSOLE_DRIVER_TABLE_ENTRY". See consolex/cTest.c for
+# an example.
+
+ifeq $(RTEMS_MVME162_MODEL,mvme162lx)
+CONSOLEX=consolex
+endif
+
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
#
# XXXX add tools
-SUB_DIRS=include startup clock console timer wrapup
+SUB_DIRS=include startup clock console $(CONSOLEX) timer wrapup
diff --git a/c/src/lib/libbsp/m68k/mvme162/README b/c/src/lib/libbsp/m68k/mvme162/README
index 4ce79e32d8..abecee32b0 100644
--- a/c/src/lib/libbsp/m68k/mvme162/README
+++ b/c/src/lib/libbsp/m68k/mvme162/README
@@ -38,6 +38,17 @@ MVME162FX modele uses XXX.
MVME162LX model uses 68LC040 and 2 ZCC chips so that it supports
4 serial ports.
+Extended Console Driver
+-----------------------
+This BSP includes an extended console driver which supports all 4 serial
+ports on the MVME162LX model. It was submitted by Katsutoshi Shibuya
+<shibuya@mxb.meshnet.or.jp>.
+
+The application can choose this driver by using "CONSOLEX_DRIVER_TABLE_ENTRY"
+in the driver table definition, in place of "CONSOLE_DRIVER_TABLE_ENTRY".
+See consolex/cTest.c for an example and consolex/README for more information.
+
+This driver is only built for the mvme162lx bsp model.
MVME162FX and DMA on the IP bus
-------------------------------
@@ -65,15 +76,21 @@ standard release.
Port Description
----------------
+This section describes the initial port effort. There have been
+additions and modifications to the bsp since this was done.
+Interestingly, this was the first bsp submitted to the RTEMS project
+and the submission offer came out of the blue with no prior
+communication with the author. :)
+
The port was done using already existing ports to the M68020 boards,
DMV152 and MVME136.
-The host system was SUN/Solaris 2.3, and the cross-development
-environment consisted of Free Software Foundation (FSF)'s GNU C
-compiler (version 2.6), GNU Assembler (version 2.3) and GNU binary
-utilities binutils version 2.5.2, built with m68k as a target. The
-recent/latest versions of other GNU programs (flex, make, etc) were
-also used at the build stage.
+The initial host development system was SUN/Solaris 2.3, and
+the cross-development environment consisted of Free Software
+Foundation (FSF)'s GNU C compiler (version 2.6), GNU Assembler
+(version 2.3) and GNU binary utilities binutils version 2.5.2,
+built with m68k as a target. The recent/latest versions of other
+GNU programs (flex, make, etc) were also used at the build stage.
In all subdirectories of the RTEMS distribution tree, the directories
mvme136 were duplicated as mvme162.
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in b/c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in
new file mode 100644
index 0000000000..0c45147de4
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in
@@ -0,0 +1,54 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH=@srcdir@
+
+PGM=${ARCH}/consolex.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=consolex
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=consolex
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
+ $(INSTALL) -m 444 $(H_FILES) ${PROJECT_RELEASE}/include
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/README b/c/src/lib/libbsp/m68k/mvme162/consolex/README
new file mode 100644
index 0000000000..719ed245eb
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/README
@@ -0,0 +1,97 @@
+#
+# $Id$
+#
+
+This driver was submitted by Katsutoshi Shibuya <shibuya@mxb.meshnet.or.jp>.
+
+Configuration
+-------------
+The application can choose this driver by using "CONSOLEX_DRIVER_TABLE_ENTRY"
+in the driver table definition, in place of "CONSOLE_DRIVER_TABLE_ENTRY".
+See consolex/cTest.c for an example and consolex/README for more information.
+
+Programmatic Usage
+------------------
+
+- You can open 9 devices; console tty00, tty01, tty02, tty03,
+ rtty00, rtty01, rtty02, rtty03
+ tty00, rtty00 and console correspond to port#1 of MVME162LX,
+ tty01 and rtty01 correspond to port#2, and so on.
+- tty0x are "cooked" devices. They support following flags on termios
+ definition;
+ ISTRIP, INLCR, IGNCR, ICRNL, IUCLC, OLCUC, ONLCR, OCRNL, ICANON, ECHO,
+ CBAUD, B38400, B19200, B9600, CSIZE, CS8, CS7, PARENB, PARODD, CSTOPB,
+- rtty0x are "raw" devices. They support following flags on termios
+ definition;
+ CBAUD, B38400, B19200, B9600, CSIZE, CS8, CS7, PARENB, PARODD, CSTOPB,
+- The default parameter is;
+ B38400, CS8, ICRNL, ONLCR, ICANON, ECHO
+ (but all flags except B38400 and CS8 will be ignored on raw device.)
+- All devices support O_NDELAY (non blocking read/write) mode operation.
+ (Non-blocking cooked mode output is valid, but will not work fine.)
+ (Non-blocking cooked mode input with ECHO flag may be blocked while sending
+ echoed character.)
+- All devices support hardware flow control by CTS/RTS.
+ (There is no way to disable it. There are no supports for soft flow control.)
+- The application can use tcgetattr or ioctl to obtain the parameters of the
+ device into struct termios.
+- The application can use tcsetattr or ioctl to set the parameters of the
+ device within the struct temios. The action argument (2nd arg) of the
+ tcsetattr must be TCSANOW.
+- On opening the device, the driver activate DTR line. On closing the device,
+ the driver deactivate DTR line.
+ If 2 or more device opening occures at the same time on the same port, only
+ the first open procedure activates DTR line, and only the last close
+ procedure deactivate it.
+- There are no device locking mechanisms. Application can open same device
+ several times.
+ But 2 simultanious reading operation on the same port will cause unexpected
+ result.
+
+Porting Notes
+-------------
+- This code can be used for any Zilog SCC based board.
+ Change the time constant parameters and SCC register base addresses.
+
+- This code is well separated into "device depended part" and "device
+ independed part".
+ They can use device independed part for any other board. The device
+ independed part requires following functions;
+
+ void SCCInitialize();
+ Initialize hardware.
+ rtems_boolean SCCGetOne(int port, char *ch);
+ Get one character from port. If no character is in the receiver buffer,
+ this function returns FALSE, otherwise TRUE.
+ char SCCGetOneBlocked(int port);
+ Get one character from port. If no character is in the receiver buffer,
+ wait it passing the CPU to the other task.
+ rtems_boolean SCCSendOne(int port, char ch);
+ Send one character via port. If the transmitter is not ready, this function
+ returns FALSE, otherwise TRUE.
+ void SCCSendOneBlocked(int port, char ch);
+ Send one character via port. Wait until the transmitter is ready, passing
+ the CPU to the other task.
+ unsigned32 SCCSetAttributes(int port, struct termios *tm);
+ Set device attribute according to the information in the struct termios.
+ c_cflags parameter (baud, parity, stopbits and code size) will be checked.
+ On the successful completion, this function should return 0.
+ unsigned32 SCCGetAttributes(int port, struct termios *tm);
+ Get device attribute according into the struct termios.
+ c_cflags parameter (baud, parity, stopbits and code size) will be set.
+ On the successful completion, this function should return 0.
+ void SCCSetDTR(port);
+ Activate DTR line.
+ void SCCResetDTR(port);
+ Deactivate DTR line.
+ void SCCSetRTS(port);
+ Activate RTS line.
+ void SCCResetRTS(port);
+ Deactivate RTS line.
+ int SCCGetCTS(port);
+ Return non zero when CTS line is activated.
+
+- If you don't want console port, undefine "CONSOLEPORT".
+
+- This code does not use ESCC feature; i.e. does not read register #4/#5/#14
+
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c b/c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c
new file mode 100644
index 0000000000..899703892d
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c
@@ -0,0 +1,75 @@
+/*
+ * Test program for consolex.
+ *
+ * NOTE: This program must be put together as an executable. :)
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <consolex.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#if ! defined(O_NDELAY)
+# if defined(solaris2)
+# define O_NDELAY O_NONBLOCK
+# elif defined(RTEMS_NEWLIB)
+# define O_NDELAY _FNBIO
+# endif
+#endif
+
+rtems_driver_address_table Device_drivers[] = {
+ CONSOLEX_DRIVER_TABLE_ENTRY
+};
+
+rtems_task Init(rtems_task_argument arg)
+{
+ char buf[128];
+ int fd;
+ struct termios t;
+
+ printf("Console test.\n");
+
+ if((fd = open("/dev/tty00",O_RDWR)) < 0){
+ printf("Can't open device.\n");
+ return;
+ }
+ tcgetattr(fd,&t);
+ t.c_cflag = B9600|CS8;
+ tcsetattr(fd,TCSANOW,&t);
+ printf("iflag=%07o, oflag=%07o, cflag=%07o, lflag=%07o\n",
+ t.c_iflag,t.c_oflag,t.c_cflag,t.c_lflag);
+
+ do{
+ write(fd,"Your name? ",11);
+ read(fd,buf,sizeof(buf));
+ write(fd,"Hi ",3);
+ write(fd,buf,strlen(buf));
+ }while(*buf != '!');
+
+ close(fd);
+
+ printf("Done.\n");
+
+ exit(0);
+}
+
+#define CONFIGURE_INIT
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
+#include <confdefs.h>
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c
new file mode 100644
index 0000000000..c868954d12
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c
@@ -0,0 +1,786 @@
+/*
+ * This file contains the MVME162LX extended console IO package.
+ *
+ * This file was created originally by
+ * On-Line Applications Research Corporation (OAR)
+ * and modified by:
+ *
+ * Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
+ *
+ * featuring support of:
+ *
+ * - Multi-SCC chip handling
+ * - Non-blocking I/O (O_NDELAY flag in libc)
+ * - Raw mode device (no CR/LF detection)
+ * - RTS/CTS flow control
+ *
+ * REMARKS: This routine requires multiple interrupt vectors
+ * from SCC_VECTOR (normaly 0x40)
+ * to SCC_VECTOR+(number of SCC chips)
+ *
+ * The original copyright follows;
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
+ * EISCAT Scientific Association. M.Savitski
+ *
+ * This material is a part of the MVME162 Board Support Package
+ * for the RTEMS executive. Its licensing policies are those of the
+ * RTEMS above.
+ *
+ */
+
+#define M162_INIT
+
+#include "consolex.h"
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define NPORTS 4 /* Number of ports */
+#define DEVICEPREFIX "tty"
+#define RAWDEVICEPREFIX "rtty"
+#define CONSOLEPORT 0 /* port# of console:
+ undef this if you do not want /dev/console */
+#define READRETRY 1 /* Maximum retry count for read one char */
+#define WRITERETRY 8 /* Maximum retry count for write one char */
+
+#define PORTFROM 0 /* for debug */
+
+static unsigned char opencount[NPORTS];
+
+/***********************************************************************
+ Ring buffer for device
+ ***********************************************************************/
+
+#define QUEUE_LENGTH 128 /* Must be 2^n number */
+
+typedef struct {
+ char buffer[QUEUE_LENGTH];
+ volatile int head;
+ volatile int tail;
+} ReceiverBuffer;
+
+#define ReceiverBufferInitialize( _buffer ) \
+ do { \
+ (_buffer)->head = (_buffer)->tail = 0; \
+ } while ( 0 )
+
+#define ReceiverBufferIsEmpty( _buffer ) \
+ ( (_buffer)->tail == (_buffer)->head )
+
+#define ReceiverBufferIsNearEmpty( _buffer ) \
+ ( (_buffer)->tail == (((_buffer)->head + 3) & (QUEUE_LENGTH-1)) )
+
+#define ReceiverBufferIsFull( _buffer ) \
+ ( (_buffer)->head == (((_buffer)->tail + 1) & (QUEUE_LENGTH-1)) )
+
+#define ReceiverBufferIsNearFull( _buffer ) \
+ ( (_buffer)->head == (((_buffer)->tail + 3) & (QUEUE_LENGTH-1)) )
+
+#define ReceiverBufferAdd( _buffer, _ch ) \
+ do { \
+ rtems_unsigned32 isrlevel; \
+ \
+ rtems_interrupt_disable( isrlevel ); \
+ (_buffer)->tail = ((_buffer)->tail+1) & (QUEUE_LENGTH-1); \
+ (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
+ rtems_interrupt_enable( isrlevel ); \
+ } while ( 0 )
+
+#define ReceiverBufferRemove( _buffer, _ch ) \
+ do { \
+ rtems_unsigned32 isrlevel; \
+ \
+ rtems_interrupt_disable( isrlevel ); \
+ (_buffer)->head = ((_buffer)->head+1) & (QUEUE_LENGTH-1); \
+ (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
+ rtems_interrupt_enable( isrlevel ); \
+ } while ( 0 )
+
+
+/***********************************************************************
+ DEVICE DEPENDED PART
+ ***********************************************************************/
+
+
+/* Time constant parameters
+ CAUTION: These parameters are for MVME162LX-213 board.
+ */
+
+#define TC38400 0x0006
+#define TC19200 0x000e
+#define TC9600 0x001e
+
+/* Re-defining SCC register control macros
+ to support Multi SCC chips */
+
+#undef scc
+static scc_regs *scc[NPORTS] = {
+ ((scc_regs * const) 0xFFF45004),
+ ((scc_regs * const) 0xFFF45000),
+ ((scc_regs * const) 0xFFF45804),
+ ((scc_regs * const) 0xFFF45800)
+};
+
+#undef ZWRITE0
+#define ZWRITE0(port, v) (scc[port]->csr = (unsigned char)(v))
+#undef ZREAD0
+#define ZREAD0(port) (scc[port]->csr)
+
+#undef ZREAD
+#define ZREAD(port, n) (ZWRITE0(port, n), (scc[port]->csr))
+#undef ZREADD
+#define ZREADD(port) (scc[port]->csr=0x08, scc[port]->csr )
+
+#undef ZWRITE
+#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))
+#undef ZWRITED
+#define ZWRITED(port, v) (scc[port]->csr = 0x08, \
+ scc[port]->csr = (unsigned char)(v))
+
+static ReceiverBuffer receiverBuffer[NPORTS];
+
+/*
+ * Control flags (DTR/DCD/RTS/CTS)
+ */
+
+static unsigned char wr4[NPORTS];
+static unsigned char wr5[NPORTS];
+#define SCCSetDTR(port) ZWRITE(port, 5, (wr5[port] |= 0x80))
+#define SCCResetDTR(port) ZWRITE(port, 5, (wr5[port] &= ~0x80))
+#define SCCSetRTS(port) ZWRITE(port, 5, (wr5[port] |= 0x02))
+#define SCCResetRTS(port) ZWRITE(port,5, (wr5[port] &= ~0x02))
+#define SCCGetDCD(port) (ZREAD0(port)&0x08)
+#define SCCGetCTS(port) (ZREAD0(port)&0x20)
+
+
+/*
+ * Interrupt handler for receiver interrupts
+ */
+
+static rtems_isr SCCReceiverISR(rtems_vector_number vector)
+{
+ register int ipend, port;
+
+ port = (vector-SCC_VECTOR)*2;
+ ZWRITE0(port, 0x38); /* reset highest IUS */
+
+ ipend = ZREAD(port, 3); /* read int pending from A side */
+
+ if(ipend == 0x04)
+ port++; /* channel B intr pending */
+ else if(ipend == 0x20)
+ ; /* channel A intr pending */
+ else
+ return;
+
+ ReceiverBufferAdd(&receiverBuffer[port], ZREADD(port));
+
+ if(ZREAD(port,1) & 0x70){ /* check error stat */
+ ZWRITE0(port, 0x30); /* reset error */
+ }
+
+ if(ReceiverBufferIsNearFull(&receiverBuffer[port]))
+ SCCResetRTS(port);
+}
+
+/*
+ * Initialize
+ */
+
+void SCCInitialize()
+{
+ int i;
+
+ for(i = PORTFROM; i < NPORTS; i+=2)
+ ZWRITE(i, 9,0xc0); /* Reset SCC Chip */
+
+ for(i = PORTFROM; i < NPORTS; i++){
+ ReceiverBufferInitialize(&(receiverBuffer[i]));
+ wr4[i] = 0x44;
+ ZWRITE(i, 4, wr4[i]); /* x16 clock, 1 stop, parity none */
+ ZWRITE(i, 1, 0); /* disable interrupts */
+ ZWRITE(i, 2, SCC_VECTOR+(i/2));
+ ZWRITE(i, 3, 0xc1); /* receiver enable, 8bits */
+ wr5[i] = 0x68;
+ ZWRITE(i, 5, wr5[i]); /* transmitter enable, 8bits, DTR&RTS off */
+ ZWRITE(i,14, 0); /* stop baudrate gen. */
+ ZWRITE(i,11,0x50); /* use baurate gen. */
+ ZWRITE(i,15, 1); /* Select WR7' */
+ ZWRITE(i, 7, 0); /* Disable all special interrupts */
+ ZWRITE(i,10, 0);
+ ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */
+ set_vector(SCCReceiverISR, SCC_VECTOR+(i/2), 1); /* install ISR */
+ ZWRITE(i, 9, 8); /* master interrupt enable */
+ ZWRITE(i,12,TC38400&0xff); /* set 38400 baud */
+ ZWRITE(i,13,TC38400>>8);
+ ZWRITE(i,14, 3); /* start baudrate gen. */
+ /* CAUTION: If your SCC use XTAL on RTxC,
+ write 1 */
+ }
+ mcchip->vector_base = 0;
+ mcchip->gen_control = 2; /* MIEN */
+ mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */
+}
+
+/*
+ * Non-blocking char input
+ */
+
+rtems_boolean SCCGetOne(int port, char *ch)
+{
+ int retry = READRETRY;
+ while(ReceiverBufferIsEmpty(&receiverBuffer[port]))
+ if(--retry <= 0)
+ return FALSE;
+
+ ReceiverBufferRemove(&receiverBuffer[port],*ch);
+
+ if(ReceiverBufferIsNearEmpty(&receiverBuffer[port]))
+ SCCSetRTS(port);
+ return TRUE;
+}
+
+/*
+ * Blocking char input
+ */
+
+char SCCGetOneBlocked(int port)
+{
+ unsigned char tmp_char;
+
+ while (!SCCGetOne(port, &tmp_char))
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ return tmp_char;
+}
+
+/*
+ * Non-blocking char input
+ * No longer supports XON/XOFF flow control.
+ */
+
+rtems_boolean SCCSendOne(int port, char ch)
+{
+ int retry = WRITERETRY;
+
+ if(!SCCGetCTS(port))
+ return FALSE;
+ while(!(ZREAD0(port) & TX_BUFFER_EMPTY))
+ if(--retry <= 0)
+ return FALSE;
+ ZWRITED(port, ch);
+ return TRUE;
+}
+
+
+/*
+ * Blocking char output
+ * No longer supports XON/XOFF flow control.
+ */
+
+void SCCSendOneBlocked(int port, char ch)
+{
+ while(!SCCSendOne(port, ch))
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+}
+
+/*
+ * Set parameters for transmission
+ */
+
+unsigned32 SCCSetAttributes(int port, struct termios *t)
+{
+ unsigned char wr3;
+
+ ZWRITE(port,1,0); /* Disable interrupt */
+ ZWRITE(port,3,0); /* Disable receiver */
+ /* Baud */
+ switch(t->c_cflag & CBAUD){
+ case B38400:
+ ZWRITE(port,12,TC38400&0xff);
+ ZWRITE(port,13,TC38400>>8);
+ break;
+ case B19200:
+ ZWRITE(port,12,TC19200&0xff);
+ ZWRITE(port,13,TC19200>>8);
+ break;
+ case B9600:
+ ZWRITE(port,12,TC9600&0xff);
+ ZWRITE(port,13,TC9600>>8);
+ break;
+ }
+
+ /* Code size */
+ wr5[port] &= 0x8f;
+ wr3 = 0; /* receiver control */
+ switch(t->c_cflag & CSIZE){
+ case CS8:
+ wr5[port] |= 0x60;
+ wr3 |= 0xc0;
+ break;
+ case CS7:
+ wr5[port] |= 0x20;
+ wr3 |= 0x40;
+ break;
+ }
+
+ /* Parity */
+ wr4[port] &= 0xf0;
+ if(t->c_cflag & PARENB)
+ wr4[port] |= 0x01;
+ if(!(t->c_cflag & PARODD))
+ wr4[port] |= 0x02;
+ /* ZWRITE(port,4,wr4[port]);*/
+
+ /* Stop bits */
+ /* wr4[port] = ZREAD(port,4) & 0xfc;*/
+ if(t->c_cflag & CSTOPB)
+ wr4[port] |= 0x0c;
+ else
+ wr4[port] |= 0x04;
+
+ ZWRITE(port,4,wr4[port]); /* TxRx parameters */
+ ZWRITE(port,5,wr5[port]); /* Transmission parameters */
+ ZWRITE(port,3,wr3|0x01); /* Enable receiver */
+ ZWRITE(port,1,0x10); /* Enable interrupt */
+
+ return 0;
+}
+
+/*
+ * Get parameters for transmission
+ */
+
+unsigned32 SCCGetAttributes(int port, struct termios *t)
+{
+ unsigned32 b;
+
+ t->c_cflag = 0;
+
+ /* Baud */
+ b = ZREAD(port,13);
+ b <<= 8;
+ b |= ZREAD(port,12);
+ switch(b){
+ case TC38400:
+ t->c_cflag |= B38400;
+ break;
+ case TC19200:
+ t->c_cflag |= B19200;
+ break;
+ case TC9600:
+ t->c_cflag |= B9600;
+ break;
+ }
+
+ /* Code size */
+ /* wr = ZREAD(port,5);*/
+ t->c_cflag &= ~CSIZE;
+ switch(wr5[port]&0x60){
+ case 0x60:
+ t->c_cflag |= CS8;
+ break;
+ case 0x20:
+ t->c_cflag |= CS7;
+ break;
+ }
+
+ /* Parity */
+ /* wr = ZREAD(port,4);*/
+ if(wr4[port] & 0x01)
+ t->c_cflag |= PARENB;
+ else
+ t->c_cflag &= ~PARENB;
+ if(wr4[port] & 0x02)
+ t->c_cflag &= ~PARODD;
+ else
+ t->c_cflag |= PARODD;
+
+ /* Stop bits */
+ /* wr = ZREAD(port,4);*/
+ if((wr4[port]&0xc0) == 0xc0)
+ t->c_cflag |= CSTOPB;
+ else
+ t->c_cflag &= ~CSTOPB;
+
+ return 0;
+}
+
+/***********************************************************************
+ DEVICE INDEPENDED PART
+ ***********************************************************************/
+
+#define LOCAL_ISTRIP 0x0001
+#define LOCAL_INLCR 0x0002
+#define LOCAL_IGNCR 0x0004
+#define LOCAL_ICRNL 0x0008
+#define LOCAL_IUCLC 0x0010
+#define LOCAL_OLCUC 0x0020
+#define LOCAL_ONLCR 0x0040
+#define LOCAL_OCRNL 0x0080
+#define LOCAL_ICANON 0x0100
+#define LOCAL_ECHO 0x0200
+
+/*
+ * Device initialize entry point
+ */
+
+rtems_device_driver consolex_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+ char devname[16];
+ int i;
+
+ SCCInitialize();
+
+#ifdef CONSOLEPORT
+ status = rtems_io_register_name("/dev/console",major,
+ (rtems_device_minor_number) CONSOLEPORT);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+#endif
+
+ for(i = PORTFROM; i < NPORTS; i++){
+ /* Register cooked ttys */
+ sprintf(devname,"/dev/%s%02d",DEVICEPREFIX,i);
+ status = rtems_io_register_name(strdup(devname),major,
+ (rtems_device_minor_number) i);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+ /* Register raw ttys */
+ sprintf(devname,"/dev/%s%02d",RAWDEVICEPREFIX,i);
+ status = rtems_io_register_name(strdup(devname),major,
+ (rtems_device_minor_number) i+NPORTS);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+ }
+
+ for(i = 0; i < NPORTS; i++){
+ opencount[i] = 0;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Open entry point
+ */
+
+rtems_device_driver consolex_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_open_close_args_t *openargs = (rtems_libio_open_close_args_t *) arg;
+ if(minor >= NPORTS)
+ minor -= NPORTS;
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ if(opencount[minor]++ == 0){
+ /* first open */
+ SCCSetDTR(minor);
+ SCCSetRTS(minor);
+ }
+ openargs->iop->data0 = LOCAL_ICRNL|LOCAL_ONLCR|LOCAL_ICANON|LOCAL_ECHO;
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Close entry point
+ */
+
+rtems_device_driver consolex_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ if(minor >= NPORTS)
+ minor -= NPORTS;
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ if(--(opencount[minor]) == 0){
+ /* closed all */
+ SCCResetRTS(minor);
+ SCCResetDTR(minor);
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * read bytes from the serial port.
+ */
+
+rtems_device_driver consolex_read_raw(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking read */
+ while(count){
+ if(!SCCGetOne(minor,buffer))
+ break;
+ buffer++;
+ count--;
+ }
+ }else{
+ /* Blocking read */
+ while(count){
+ *buffer = SCCGetOneBlocked(minor);
+ buffer++;
+ count--;
+ }
+ }
+
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver consolex_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+ unsigned32 mode;
+
+ if(minor >= NPORTS)
+ return consolex_read_raw(major,minor-NPORTS,arg);
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+ mode = rw_args->iop->data0;
+
+ /* Cooked read */
+ while(count){
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking read */
+ if(!SCCGetOne(minor,buffer))
+ break;
+ }else{
+ /* Blocking read */
+ *buffer = SCCGetOneBlocked(minor);
+ }
+ if((mode&LOCAL_ICANON) && (*buffer == '\b')){
+ if(buffer > (char *)(rw_args->buffer)){
+ buffer--;
+ count++;
+ if(mode&LOCAL_ECHO){
+ SCCSendOneBlocked(minor,'\b');
+ SCCSendOneBlocked(minor,' ');
+ SCCSendOneBlocked(minor,'\b');
+ }
+ }
+ continue;
+ }
+ if((mode&LOCAL_IGNCR) && (*buffer == '\r'))
+ continue;
+ if((mode&LOCAL_INLCR) && (*buffer == '\n'))
+ *buffer = '\r';
+ if((mode&LOCAL_ICRNL) && (*buffer == '\r'))
+ *buffer = '\n';
+ if((mode&LOCAL_IUCLC) && isupper(*buffer))
+ *buffer = tolower(*buffer);
+ if(mode&LOCAL_ISTRIP)
+ *buffer &= 0x7f;
+ if(mode&LOCAL_ECHO){
+ /* Caution: Echo back is blocking output */
+ SCCSendOneBlocked(minor,*buffer);
+ }
+ if((mode&LOCAL_ICANON) && (*buffer == '\n')){
+ buffer++;
+ count--;
+ if(count)
+ *buffer = 0;
+ if((mode&LOCAL_ECHO)&&(mode&LOCAL_ONLCR))
+ SCCSendOneBlocked(minor,'\r');
+ break; /* finish reading */
+ }
+ buffer++;
+ count--;
+ }
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+/*
+ * write bytes to the serial port.
+ */
+
+rtems_device_driver consolex_write_raw(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking write */
+ while(count){
+ if(!SCCSendOne(minor,*buffer))
+ break;
+ buffer++;
+ count--;
+ }
+ }else{
+ /* Blocking write */
+ while(count){
+ SCCSendOneBlocked(minor,*buffer);
+ buffer++;
+ count--;
+ }
+ }
+
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver consolex_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+ char ch;
+ unsigned32 mode;
+
+ if(minor >= NPORTS)
+ return consolex_write_raw(major,minor-NPORTS,arg);
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+ mode = rw_args->iop->data0;
+
+ /* Cooked write */
+ while(count){
+ ch = *buffer;
+ if((mode&LOCAL_ONLCR) && (ch == '\n')){ /* Output CRLF */
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking write */
+ if(!SCCSendOne(minor,'\r'))
+ break;
+ }else{
+ SCCSendOneBlocked(minor,'\r');
+ }
+ }
+ if((mode&LOCAL_OCRNL) && (ch == '\r'))
+ ch = '\n';
+ if((mode&OLCUC) && (islower(ch)))
+ ch = toupper(ch);
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking write */
+ if(!SCCSendOne(minor,ch))
+ break;
+ }else{
+ SCCSendOneBlocked(minor,ch);
+ }
+ buffer++;
+ count--;
+ }
+
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+/*
+ * IO Control entry point
+ */
+
+rtems_device_driver consolex_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
+ struct termios *tm = ioarg->buffer;
+ unsigned32 *mode = &(ioarg->iop->data0);
+
+ if(minor >= NPORTS)
+ minor -= NPORTS;
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ switch(ioarg->command){
+ case RTEMS_IO_GET_ATTRIBUTES:
+ tm->c_iflag = tm->c_oflag = tm->c_cflag = tm->c_lflag = 0;
+ if(*mode & LOCAL_ISTRIP)
+ tm->c_iflag |= ISTRIP;
+ if(*mode & LOCAL_INLCR)
+ tm->c_iflag |= INLCR;
+ if(*mode & LOCAL_IGNCR)
+ tm->c_iflag |= IGNCR;
+ if(*mode & LOCAL_ICRNL)
+ tm->c_iflag |= ICRNL;
+ if(*mode & LOCAL_IUCLC)
+ tm->c_iflag |= IUCLC;
+ if(*mode & LOCAL_OLCUC)
+ tm->c_oflag |= OLCUC;
+ if(*mode & LOCAL_ONLCR)
+ tm->c_oflag |= ONLCR;
+ if(*mode & LOCAL_OCRNL)
+ tm->c_oflag |= OCRNL;
+ if(*mode & LOCAL_ICANON)
+ tm->c_lflag |= ICANON;
+ if(*mode & LOCAL_ECHO)
+ tm->c_lflag |= ECHO;
+ ioarg->ioctl_return = SCCGetAttributes(minor,tm);
+ break;
+ case RTEMS_IO_SET_ATTRIBUTES:
+ *mode = 0;
+ if(tm->c_iflag & ISTRIP)
+ *mode |= LOCAL_ISTRIP;
+ if(tm->c_iflag & INLCR)
+ *mode |= LOCAL_INLCR;
+ if(tm->c_iflag & IGNCR)
+ *mode |= LOCAL_IGNCR;
+ if(tm->c_iflag & ICRNL)
+ *mode |= LOCAL_ICRNL;
+ if(tm->c_iflag & IUCLC)
+ *mode |= LOCAL_IUCLC;
+ if(tm->c_oflag & OLCUC)
+ *mode |= LOCAL_OLCUC;
+ if(tm->c_oflag & ONLCR)
+ *mode |= LOCAL_ONLCR;
+ if(tm->c_oflag & OCRNL)
+ *mode |= LOCAL_OCRNL;
+ if(tm->c_lflag & ICANON)
+ *mode |= LOCAL_ICANON;
+ if(tm->c_lflag & ECHO)
+ *mode |= LOCAL_ECHO;
+ ioarg->ioctl_return = SCCSetAttributes(minor,tm);
+ break;
+ default:
+ return RTEMS_NOT_DEFINED;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h
new file mode 100644
index 0000000000..b7ccb2a464
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h
@@ -0,0 +1,93 @@
+/* consolex.h
+ *
+ * This file describes the Extended Console Device Driver
+ * This driver provides support for the standard C Library.
+ *
+ * This file was created originally by
+ * On-Line Applications Research Corporation (OAR)
+ * and modified by:
+ *
+ * Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
+ *
+ * featuring support of:
+ *
+ * - Multi-SCC chip handling
+ * - Non-blocking I/O (O_NDELAY flag in libc)
+ * - Raw mode device (no CR/LF detection)
+ * - RTS/CTS flow control
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ */
+
+#ifndef _CONSOLEX_DRIVER_h
+#define _CONSOLEX_DRIVER_h
+
+#include <rtems.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CONSOLEX_DRIVER_TABLE_ENTRY \
+ { consolex_initialize, consolex_open, consolex_close, \
+ consolex_read, consolex_write, consolex_control }
+
+rtems_device_driver consolex_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+/* Low level IO functions */
+void SCCInitialize();
+rtems_boolean SCCGetOne(int port, char *ch);
+char SCCGetOneBlocked(int port);
+rtems_boolean SCCSendOne(int port, char ch);
+void SCCSendOneBlocked(int port, char ch);
+unsigned32 SCCSetAttributes(int port, struct termios *t);
+unsigned32 SCCGetAttributes(int port, struct termios *t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libc/Makefile.in b/c/src/lib/libc/Makefile.in
index 9b5c9238d6..ea9f78709e 100644
--- a/c/src/lib/libc/Makefile.in
+++ b/c/src/lib/libc/Makefile.in
@@ -12,7 +12,7 @@ LIB=${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES=__gettod __brk __times malloc syscalls \
- no_libc newlibc newlibif support unixlibc libio hosterr
+ no_libc newlibc newlibif support unixlibc libio hosterr tcattr
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
diff --git a/c/src/lib/libc/libio.h b/c/src/lib/libc/libio.h
index c79dfc2e33..d77480e4af 100644
--- a/c/src/lib/libc/libio.h
+++ b/c/src/lib/libc/libio.h
@@ -121,4 +121,11 @@ void rtems_register_libio_handler(int handler_flag,
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
+/*
+ * IOCTL values
+ */
+
+#define RTEMS_IO_GET_ATTRIBUTES 1
+#define RTEMS_IO_SET_ATTRIBUTES 2
+
#endif /* _RTEMS_LIBIO_H */
diff --git a/c/src/lib/libc/newlibif.c b/c/src/lib/libc/newlibif.c
index 5b59554428..aca1f369f7 100644
--- a/c/src/lib/libc/newlibif.c
+++ b/c/src/lib/libc/newlibif.c
@@ -87,4 +87,34 @@ fstat(int fd,
* getpid and kill are provided directly by rtems
*/
+/*
+ * ioctl -- IO control
+ */
+
+int
+ioctl(int fd, int request, void *argp)
+{
+ return __rtems_ioctl(fd,request,argp);
+}
+
+/*
+ * tcgetattr/tcsetattr -- get/set attributes of a device.
+ *
+ * by K.Shibuya
+ */
+
+int
+tcgetattr(int fd, struct termios *tp)
+{
+ return __rtems_ioctl(fd,RTEMS_IO_GET_ATTRIBUTES,tp);
+}
+
+int
+tcsetattr(int fd, int opt, struct termios *tp)
+{
+ if(opt != TCSANOW)
+ return -1;
+ return __rtems_ioctl(fd,RTEMS_IO_SET_ATTRIBUTES,tp);
+}
+
#endif
diff --git a/c/src/lib/libc/tcattr.c b/c/src/lib/libc/tcattr.c
new file mode 100644
index 0000000000..aaa5ff6e6e
--- /dev/null
+++ b/c/src/lib/libc/tcattr.c
@@ -0,0 +1,40 @@
+/*
+ * This file contains the RTEMS implementation of the POSIX API
+ * routines tcgetattr and tcsetattr.
+ *
+ * $Id$
+ *
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+#include "internal.h"
+#include "libio.h"
+
+/*
+ * tcgetattr/tcsetattr -- get/set attributes of a device.
+ *
+ * submitted by K.Shibuya
+ */
+
+int
+tcgetattr(int fd, struct termios *tp)
+{
+ return __rtems_ioctl(fd,RTEMS_IO_GET_ATTRIBUTES,tp);
+}
+
+int
+tcsetattr(int fd, int opt, struct termios *tp)
+{
+ if(opt != TCSANOW)
+ return -1;
+ return __rtems_ioctl(fd,RTEMS_IO_SET_ATTRIBUTES,tp);
+}
+
+#endif