home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-14 | 56.9 KB | 2,017 lines |
- Newsgroups: comp.sources.misc
- From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
- Subject: v32i067: ecu - ECU Asynchronous Communications v3.20, Part32/40
- Message-ID: <1992Sep15.153107.19838@sparky.imd.sterling.com>
- X-Md4-Signature: 92638c50d41db08f422cb82039167f3a
- Date: Tue, 15 Sep 1992 15:31:07 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
- Posting-number: Volume 32, Issue 67
- Archive-name: ecu/part32
- Environment: SCO,XENIX,ISC,SUNOS,SYSVR4,HDB,Curses
- Supersedes: ecu: Volume 21, Issue 53-89
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # this is ecu320.32 (part 32 of ecu320)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file fasi/RELEASENOTES continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 32; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping fasi/RELEASENOTES'
- else
- echo 'x - continuing file fasi/RELEASENOTES'
- sed 's/^X//' << 'SHAR_EOF' >> 'fasi/RELEASENOTES' &&
- X but is checked by the kernel config program.
- X
- X The gcc (GNU cc) support was removed because gcc's object
- X file wants to link in some "helpful" functions that aren't
- X contained in the kernel. But anyway, FAS is tuned so carefully
- X and depends on the optimization behaviour of the AT&T
- X standard C compiler that gcc won't have any advantages.
- X
- X I changed the method with which the `fas_test_device' function
- X waits for certain events. The `delay' function was used
- X for that purpose but it turned out that with some flavors
- X of UNIX it is prohibited to use this function during the
- X xxinit phase of the boot process. Now a simple timeout loop
- X is used instead.
- X
- X Removed the ADAPT_TIME mechanismn introduced in release 2.05.
- X
- X The open() call now returns an `EBUSY' error number if the
- X device is already open and can't be opened in the desired
- X mode at this time.
- X
- X The handling of the RING signal needed fixing. Unlike the other
- X three modem status lines RING generates an interrupt only at
- X the trailing edge.
- X
- X No SIGHUP signal is sent any more if an ioctl call clears
- X the CLOCAL termio(7) flag while there is no carrier present.
- X SIGHUP is only sent if the actual DCD modem line drops.
- X
- X The files *-mux4 were renamed to *-ast4 because this type of
- X card was originally developed by AST (AST 4-port card).
- X
- X ------------------------------------------------------------
- X
- X release 2.08 Sun Jan 13, 1991
- X
- X New Features:
- X
- X Bell Tech/Intel UNIX 3.2 is supported.
- X
- X SCO Xenix 286 is also supported now. Thanks to Nickolay Saukh
- X (nms@saukh.rd.jvd.su) for providing the patches.
- X
- X The Bell Tech HUB-6 card can be used with FAS. Thanks to
- X Keith Walker (kew@cims2.UUCP) for the patches.
- X
- X For AT&T derived flavors of UNIX there is a line automatically
- X added to the kernel description file that makes the adding
- X and removing of FAS possible via the `kconfig' program. Thanks
- X to John Adams (johna@grumpy.boston.ma.us) for this idea.
- X
- X There is a mechanismn now that prevents excessive modem status
- X interrupts caused by crosstalking between wires or by a loose
- X cable.
- X
- X You can disable the FIFOs in a UART by "oring" the macro
- X `NO_FIFO' to the base port address of this device. This is
- X useful for mouse devices where you need immediate response
- X to the mouse movement.
- X
- X The meaning of the bit mapped part of the minor device
- X numbers has changed. Some rather useless functions were
- X removed in favor of more control over the hardware handshake
- X modes. Even systems where the SCO RTSFLOW/CTSFLOW termio(7)
- X flags are not available can now use half duplex hardware
- X flow control (selected via the minor device number).
- X
- X The assignment of RS232C lines to certain FAS functions
- X is even more flexible now. This allows to connect two
- X UNIX systems (with FAS) via a null modem cable, running
- X a getty at both ends. For more details, read the paragraph
- X about CABLING in the README file.
- X
- X A special handling of the NS16550A input FIFO was introduced.
- X This causes multiple receiver interrupts (on the same IRQ
- X line) to be synchronized so that only one interrupt is
- X necessary to process all receiving ports. This reduces the
- X interrupt handling overhead and therefor results in lower
- X CPU load for concurrent serial input at high speeds.
- X
- X The `fas_event' function processes all scheduled events
- X for all units with one single call. Previously, every unit
- X launched its own timeout() call if there was work to
- X do. This could lead to up to 16 timeouts at the same time,
- X resulting in some timeout handling overhead. This overhead
- X is minimized now.
- X
- X Bug Fixes:
- X
- X There were two bugs that could cause a port to lock up,
- X resulting in an immortal process.
- X
- X Almost any kernel sleep is killable now (at least with one or
- X two `kill -9'). Therefor, there should be no more immortal
- X processes. Even killing a process that is hanging in a
- X close-on-exit call is possible.
- X
- X The meaning of the RTSFLOW/CTSFLOW termio(7) flags was converted
- X to what SCO had in mind (half duplex flow control). This is for
- X compatibility reasons. Full duplex RTS/CTS hardware flow control
- X is still possible via the minor device number method. Thanks to
- X Dmitry V. Volodin (dvv@hq.demos.su) for providing me with the
- X necessary knowledge.
- X
- X If a process is already sleeping in a getty open it will only
- X unblock on DCD low->high. In particular, if in the meantime
- X the device was open for dialout and DCD is still present if
- X the getty open takes over again this won't unblock the getty
- X open any more.
- X
- X And there were, as usual, a number of other small bug fixes.
- SHAR_EOF
- echo 'File fasi/RELEASENOTES is complete' &&
- chmod 0644 fasi/RELEASENOTES ||
- echo 'restore of fasi/RELEASENOTES failed'
- Wc_c="`wc -c < 'fasi/RELEASENOTES'`"
- test 23494 -eq "$Wc_c" ||
- echo 'fasi/RELEASENOTES: original size 23494, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= fasi/Space.c ==============
- if test -f 'fasi/Space.c' -a X"$1" != X"-c"; then
- echo 'x - skipping fasi/Space.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting fasi/Space.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fasi/Space.c' &&
- X/* Async device configuration file for the FAS async driver. */
- X
- X/*
- X * COM1(STD) + COM2(DIGIBOARD PC-8)
- X */
- X/*+:EDITS:*/
- X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
- X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
- X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
- X/*:01-20-1991-16:17-wht@n4hgf-add fas_names */
- X/*:01-20-1991-05:01-wht@n4hgf-changed buffer sizes */
- X/*:01-16-1991-22:13-wht@n4hgf-creation */
- X
- X/* FAS was developed by ( ==> BUT DO NOT CONTACT HIM ABOUT THIS HACK )
- XUwe Doering INET : gemini@geminix.in-berlin.de
- XBillstedter Pfad 17 b UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
- X1000 Berlin 20
- XGermany
- X*/
- X
- X/* Alas, SCO idinstall has no -z (Define) option like ISC does */
- X#if !defined(FASI)
- X#define FASI
- X#endif
- X#if !defined(SCO)
- X#define SCO
- X#endif
- X
- X#if defined(FASI)
- X/* {quan,irq,addr1-addr2,type} */
- Xchar *fasi_space_ident =
- X"FAS/i 2.08:{1,4,03f8-03ff,COM1},{8,3,0210-024f,DIGI-PC8}";
- X#endif /* FASI */
- X
- X#if !defined (M_I286) && !defined(__STDC__) && !defined(__GNUC__)
- X#ident "@(#)space.c 2.08.0 COM1(STD) + COM2(DIGIBOARD PC-8)";
- X#endif
- X
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/signal.h>
- X#include <sys/buf.h>
- X#include <sys/dir.h>
- X#if defined (XENIX)
- X#include <sys/page.h>
- X#include <sys/seg.h>
- X#endif
- X#include <sys/user.h>
- X#include <sys/errno.h>
- X#include <sys/tty.h>
- X#include <sys/conf.h>
- X#include <sys/sysinfo.h>
- X#include <sys/file.h>
- X#if !defined (XENIX) && !defined(CBAUD)
- X#include <sys/termio.h>
- X#endif
- X#include <sys/ioctl.h>
- X#if !defined(FASI)
- X#include <macros.h>
- X#endif
- X#if defined (HAVE_VPIX)
- X#if !defined (XENIX)
- X#include <sys/tss.h>
- X#include <sys/immu.h>
- X#include <sys/region.h>
- X#endif
- X#include <sys/proc.h>
- X#include <sys/v86.h>
- X#endif
- X
- X#if defined (XENIX)
- X#include "fas.h"
- X#include "digi-pc8.h"
- X#else
- X#include <local/fas.h>
- X#include <local/digi-pc8.h>
- X#endif
- X
- X/* This is the number of devices to be handled by this driver.
- X You may define up to 16 devices. If this number is changed
- X the arrays below must be filled in accordingly.
- X*/
- X#define NUM_PHYSICAL_UNITS 9
- X
- X#if NUM_PHYSICAL_UNITS > MAX_UNITS
- X#undef NUM_PHYSICAL_UNITS
- X#define NUM_PHYSICAL_UNITS MAX_UNITS
- X#endif
- X
- X/* let the driver know the number of devices */
- Xuint fas_physical_units = NUM_PHYSICAL_UNITS;
- X
- X/* array of base port addresses
- X If you deliberately want to force off the FIFOs of a UART you have
- X to "or" the NO_FIFO macro to its base port address. This is useful
- X for mouse devices where you need immediate response to the mouse
- X movement.
- X*/
- Xulong fas_port [NUM_PHYSICAL_UNITS] =
- X{
- X 0x3f8,
- X COM21, COM22, COM23, COM24,COM25, COM26, COM27, COM28
- X};
- X
- X/*
- X * array of port names
- X * Note this is a kludge to enable kmem seeking programs to
- X * determine which tty is associated with which tty struct
- X * and is <yetch> duplication of information appearing in
- X * the Node (/etc/node.d/fas) file
- X */
- X#if defined(FASI)
- Xstruct fas_name fas_names[NUM_PHYSICAL_UNITS * 2] =
- X{
- X {"1a"},
- X {"2a"}, {"2b"},{"2c"},{"2d"},{"2e"},{"2f"},{"2g"},{"2h"},
- X {"1A"},
- X {"2A"}, {"2B"},{"2C"},{"2D"},{"2E"},{"2F"},{"2G"},{"2H"}
- X};
- X#endif
- X
- X/* array of interrupt vectors */
- Xuint fas_vec [NUM_PHYSICAL_UNITS] =
- X{
- X 4,
- X 3,3,3,3,3,3,3,3
- X};
- X
- X/* initialization sequence for serial card
- X This array contains pairs of values of the form:
- X
- X portaddress, value,
- X :
- X :
- X portaddress, value,
- X 0
- X
- X For every line `value' will be written to `portaddress'. If
- X `value' is replaced with the macro `READ_PORT' then a value
- X is read from `portaddress' instead. The value itself will be
- X discarded. Therefor this makes only sense if the read access
- X to the port has a side effect like setting or resetting
- X certain flags.
- X
- X NOTE: This array *must* be terminated with a value of 0
- X in the portaddress column!
- X*/
- Xuint fas_init_seq [] =
- X{
- X 0
- X};
- X
- X/* initial modem control port info
- X This value is ored into the modem control value for each UART. This is
- X normaly used to force out2 which is used to enable the interrupts of
- X the standard com1 and com2 ports. Several brands of cards have modes
- X that allow them to work in compatible mode like com1 and com2 or as a
- X shared interrupts card. One of these cards is the AST 4-port card. When
- X this card is used in shared interrupts mode out2 must _not_ be set.
- X
- X Note: This is one of the major trouble-spots with shared interrupts
- X cards. Check your manual.
- X*/
- Xuint fas_mcb [NUM_PHYSICAL_UNITS] =
- X{
- X MC_SET_OUT2,
- X MC_SET_OUT2, MC_SET_OUT2, MC_SET_OUT2, MC_SET_OUT2,
- X MC_SET_OUT2, MC_SET_OUT2, MC_SET_OUT2, MC_SET_OUT2
- X};
- X
- X/* array of modem control flags
- X You can choose which signals to use for modem control. See fas.h
- X for possible names and values. Whether or not modem control is
- X used is determined by the minor device number at open time.
- X*/
- Xulong fas_modem [NUM_PHYSICAL_UNITS] =
- X{
- X EO_DTR | EI_DTR | CA_DCD,
- X EO_DTR | EI_DTR | CA_DCD, EO_DTR | EI_DTR | CA_DCD,
- X EO_DTR | EI_DTR | CA_DCD, EO_DTR | EI_DTR | CA_DCD,
- X EO_DTR | EI_DTR | CA_DCD, EO_DTR | EI_DTR | CA_DCD,
- X EO_DTR | EI_DTR | CA_DCD, EO_DTR | EI_DTR | CA_DCD
- X};
- X
- X/* array of hardware flow control flags
- X You can choose which signals to use for hardware handshake. See fas.h
- X for possible names and values. Whether or not hardware handshake is
- X used is determined by the minor device number at open time and by the
- X RTSFLOW/CTSFLOW termio(7) flags.
- X*/
- Xulong fas_flow [NUM_PHYSICAL_UNITS] =
- X{
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS,
- X HI_RTS | HO_CTS_ON_DSR | HX_RTS
- X};
- X
- X/* array of control register addresses
- X There are serial boards available that have all serial ports
- X multiplexed to one address location in order to save I/O address
- X space (Bell Tech HUB-6 card etc.). This multiplexing is controlled
- X by a special register that needs to be written to before the actual
- X port registers can be accessed. This array contains the addresses
- X of these special registers.
- X Enter the addresses on a per unit base. An address of zero
- X disables this feature.
- X*/
- Xuint fas_ctl_port [NUM_PHYSICAL_UNITS] =
- X{
- X 0,
- X 0, 0, 0, 0, 0, 0, 0, 0
- X};
- X
- X/* array of control register values
- X These values are written to the corresponding control register
- X before the first access to the actual port registers. If not only
- X entire UART chips (blocks of 8 contiguous addresses) but even the
- X single registers of the UART chips need to be multiplexed to one
- X address you have to "or" a bit mask (shifted 8 times to the left)
- X to the control register value. This mask determines at which bit
- X locations the UART chip register number is "xored" into the control
- X register value at runtime. This implies that you can also use
- X negative logic by setting the bits in the control register value
- X to 1 at the locations corresponding to the bit mask.
- X*/
- Xuint fas_ctl_val [NUM_PHYSICAL_UNITS] =
- X{
- X 0,
- X 0, 0, 0, 0, 0, 0, 0, 0
- X};
- X
- X/* additional configurations for shared interrupts boards
- X If you have a shared interrupts board, you may have to acknowledge
- X interrupts by writing to a special register. The following arrays
- X contain the special register addresses and the corresponding values
- X that are written to them in response to an interrupt.
- X*/
- X
- X/* array of int ack register addresses
- X These registers are written to every time after all interrupt
- X sources in all of the UARTs that are tied to the corresponding
- X interrupt vector have been cleared.
- X Enter the addresses on a per vector base. An address of zero
- X disables this feature.
- X*/
- Xuint fas_int_ack_port [NUM_INT_VECTORS] =
- X{
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0
- X};
- X
- X/* array of int ack values
- X These values are written to the corresponding int ack register
- X in response to an interrupt.
- X*/
- Xuint fas_int_ack [NUM_INT_VECTORS] =
- X{
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0,
- X 0, 0, 0, 0
- X};
- X
- X/* NOTHING NEEDS TO BE CHANGED BELOW THIS LINE.
- X ============================================
- X*/
- X
- X/* array of structures to hold all info for a physical minor device */
- Xstruct fas_info fas_info [NUM_PHYSICAL_UNITS];
- X
- X/* array of ttys for logical minor devices */
- Xstruct tty fas_tty [NUM_PHYSICAL_UNITS * 2];
- X
- X/* array of pointers to fas_info structures
- X this prevents time consuming multiplications for index calculation
- X*/
- Xstruct fas_info *fas_info_ptr [NUM_PHYSICAL_UNITS];
- X
- X/* array of pointers to fas_tty structures
- X this prevents time consuming multiplications for index calculation
- X*/
- Xstruct tty *fas_tty_ptr [NUM_PHYSICAL_UNITS * 2];
- SHAR_EOF
- chmod 0644 fasi/Space.c ||
- echo 'restore of fasi/Space.c failed'
- Wc_c="`wc -c < 'fasi/Space.c'`"
- test 8785 -eq "$Wc_c" ||
- echo 'fasi/Space.c: original size 8785, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= fasi/System ==============
- if test -f 'fasi/System' -a X"$1" != X"-c"; then
- echo 'x - skipping fasi/System (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting fasi/System (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fasi/System' &&
- Xfas Y 1 7 1 4 3f8 3ff 0 0
- Xfas Y 1 7 1 3 210 250 0 0
- SHAR_EOF
- chmod 0644 fasi/System ||
- echo 'restore of fasi/System failed'
- Wc_c="`wc -c < 'fasi/System'`"
- test 52 -eq "$Wc_c" ||
- echo 'fasi/System: original size 52, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= fasi/digi-pc8.h ==============
- if test -f 'fasi/digi-pc8.h' -a X"$1" != X"-c"; then
- echo 'x - skipping fasi/digi-pc8.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting fasi/digi-pc8.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fasi/digi-pc8.h' &&
- X/*+-------------------------------------------------------------------------
- X digi-pc8.h - Digiboard PC-8 with SCO COM2 addressing conventions
- X wht@n4hgf.Mt-Park.GA.US
- X--------------------------------------------------------------------------*/
- X/*+:EDITS:*/
- X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
- X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
- X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
- X/*:12-24-1991-03:23-wht@n4hgf-creation */
- X
- X#define COM21 0x210 /* digi board */
- X#define COM22 0x218
- X#define COM23 0x220
- X#define COM24 0x228
- X#define COM25 0x230
- X#define COM26 0x238
- X#define COM27 0x240
- X#define COM28 0x248
- X#define COM2S 0x250
- X
- X/* vi: set tabstop=4 shiftwidth=4: */
- X/* end of digi-pc8.h */
- SHAR_EOF
- chmod 0644 fasi/digi-pc8.h ||
- echo 'restore of fasi/digi-pc8.h failed'
- Wc_c="`wc -c < 'fasi/digi-pc8.h'`"
- test 717 -eq "$Wc_c" ||
- echo 'fasi/digi-pc8.h: original size 717, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= fasi/fas.c ==============
- if test -f 'fasi/fas.c' -a X"$1" != X"-c"; then
- echo 'x - skipping fasi/fas.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting fasi/fas.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fasi/fas.c' &&
- X/* FAS Final Async Solution driver for 286/386 versions of system V UNIX */
- X
- X/* FAS was developed by
- XUwe Doering INET : gemini@geminix.in-berlin.de
- XBillstedter Pfad 17 b UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
- X1000 Berlin 20
- XGermany
- X*/
- X/*+:EDITS:*/
- X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
- X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
- X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
- X/*:06-04-1991-19:41-wht@n4hgf-add FASIC_SIP_CHANGE */
- X/*:02-05-1991-12:13-wht@n4hgf-apply 2.08b2->2.08.0 diffs */
- X/*:01-20-1991-05:01-wht@n4hgf-changed buffer sizes */
- X
- X#if defined(FASI)
- Xchar *fasi_driver_ident = "FAS/i 2.08.01";
- X#endif /* FASI */
- X
- X#if !defined (M_I286) && !defined(__STDC__)
- X#ident "@(#)fas.c 2.08"
- X#endif
- X
- X/* Note: This source code was quite heavily optimized for speed. You
- X may wonder that register variables aren't used everywhere.
- X This is because there is an overhead in memory accesses
- X when using register variables. As you may know data accesses
- X usually need much more wait states on the memory bus than
- X code accesses (because of page or cache misses). Therefor,
- X saving some data accesses has higher priority than saving
- X code accesses.
- X
- X You may also note some not very elegant constructions that
- X may be intentional because they are faster. If you want to
- X make style improvements you should check the assembler output
- X whether this wouldn't slow things down.
- X
- X Decisions for speed optimization were based on assembler
- X listings produced by the standard UNIX V 3.X/386 C compiler.
- X*/
- X
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/signal.h>
- X#include <sys/buf.h>
- X#include <sys/dir.h>
- X#if defined (XENIX)
- X#include <sys/page.h>
- X#include <sys/seg.h>
- X#endif
- X#include <sys/user.h>
- X#include <sys/errno.h>
- X#include <sys/tty.h>
- X#include <sys/conf.h>
- X#include <sys/sysinfo.h>
- X#include <sys/file.h>
- X#if !defined (XENIX) && !defined(CBAUD)
- X#include <sys/termio.h>
- X#endif
- X#include <sys/ioctl.h>
- X#if !defined(FASI)
- X#include <macros.h>
- X#endif
- X#if defined (HAVE_VPIX)
- X#if !defined (XENIX)
- X#include <sys/tss.h>
- X#include <sys/immu.h>
- X#include <sys/region.h>
- X#endif
- X#include <sys/proc.h>
- X#include <sys/v86.h>
- X#endif
- X
- X#if defined (XENIX)
- X#include "fas.h"
- X#else
- X#include <local/fas.h>
- X#if !defined (NO_ASM)
- X#include <sys/inline.h>
- X#endif
- X#endif
- X
- X#if defined (SCO) || defined (XENIX)
- X#define asyputchar sioputchar
- X#define asygetchar siogetchar
- X#endif
- X
- X#if defined (XENIX) || defined (NO_ASM)
- X#define intr_disable() old_level = SPLINT ()
- X#define intr_restore() (void) splx (old_level)
- X#define REGVAR
- X#else
- X/* This is a terrible ugly kludge to speed up the `inb' and `outb'
- X functions. I.e., originally, the `outb' inline function had an
- X overhead of four data memory accesses for parameter passing. This
- X parameter passing actually consumed more clock cycles than the
- X assembler `outb' command itself. Although this solution can't
- X prevent unnessessary register moves it limits them at least to
- X register to register moves that are much faster. You need a
- X line like the following in the declaration part of every
- X function that uses `inb' or `outb' calls:
- X
- X REGVAR;
- X
- X This hack should work with every compiler that knows about the
- X UNIX V 3.X/386 standard compiler's inline assembler directives.
- X*/
- X
- Xasm void loadal (val)
- X{
- X%reg val;
- X movl val,%eax
- X%mem val;
- X movb val,%al
- X}
- X
- Xasm void loaddx (val)
- X{
- X%reg val;
- X movl val,%edx
- X%mem val;
- X movw val,%dx
- X}
- X
- Xasm int outbyte ()
- X{
- X outb (%dx)
- X}
- X
- Xasm int inbyte ()
- X{
- X xorl %eax,%eax
- X inb (%dx)
- X}
- X
- X/* The port parameter of the `outb' macro must be one of the predefined
- X port macros from `fas.h' or a simple uint variable (no indirection
- X is allowed). Additionally, `fip' must be a register variable in the
- X functions where `outb' is used. This prevents the destruction of the
- X `eax' CPU register while loading the `edx' register with the port
- X address. This is highly compiler implementation specific.
- X*/
- X#define outb(port,val) (regvar = (val), loadal (regvar), regvar = (port), loaddx (regvar), outbyte ())
- X
- X#define inb(port) (regvar = (port), loaddx (regvar), inbyte ())
- X
- X#define REGVAR register uint regvar
- X
- X/* This function inserts the address optimization assembler pseudo-op
- X wherever called.
- X*/
- X
- Xasm void optim ()
- X{
- X .optim
- X}
- X
- X/* This dummy function has nothing to do but to call optim so that
- X the `.optim' assembler pseudo-op will be included in the assembler
- X file. This must be the first of all functions.
- X*/
- X
- X#if defined (OPTIM) /* Define for uPort, ISC doesn't know about */
- Xstatic void /* `.optim', but has turned on optimization by */
- Xdummy () /* default, so we don't need it there anyway. */
- X{
- X optim ();
- X}
- X#endif
- X#endif /* XENIX || NO_ASM */
- X
- X/* functions provided by this driver */
- Xint fasinit ();
- Xint fasopen ();
- Xint fasclose ();
- Xint fasread ();
- Xint faswrite ();
- Xint fasioctl ();
- Xint fasintr ();
- X#if defined (NEED_PUT_GETCHAR)
- Xint asyputchar ();
- Xint asygetchar ();
- X#endif
- X#if defined (NEED_INIT8250)
- Xint init8250 ();
- X#endif
- Xstatic int fas_proc ();
- Xstatic void fas_param ();
- Xstatic void fas_fproc ();
- Xstatic void fas_mproc ();
- Xstatic uint fas_rproc ();
- Xstatic void fas_xproc ();
- Xstatic void fas_event ();
- X#if defined (HAVE_VPIX)
- Xstatic int fas_vpix_sr ();
- X#endif
- Xstatic void fas_rxfer ();
- Xstatic void fas_xxfer ();
- Xstatic void fas_ihlw_check ();
- Xstatic void fas_hdx_check ();
- Xstatic void fas_hangup ();
- Xstatic void fas_timeout ();
- Xstatic void fas_cmd ();
- Xstatic void fas_open_device ();
- Xstatic void fas_close_device ();
- Xstatic uint fas_make_ctl_val ();
- Xstatic int fas_test_device ();
- X
- X/* external functions used by this driver */
- Xextern int ttinit ();
- Xextern int ttiocom ();
- Xextern int ttyflush ();
- Xextern int SPLINT ();
- Xextern int SPLWRK ();
- Xextern int splx ();
- Xextern int sleep ();
- Xextern int wakeup ();
- Xextern void longjmp ();
- Xextern int signal ();
- Xextern int timeout ();
- Xextern int untimeout ();
- Xextern int printf ();
- X#if defined (SCO) || defined (XENIX)
- Xextern int printcfg ();
- X#endif
- X#if defined (HAVE_VPIX)
- Xextern int fubyte ();
- Xextern int subyte ();
- Xextern int v86setint ();
- X#endif
- X#if defined (XENIX)
- Xextern int inb ();
- Xextern int outb ();
- X#endif
- X
- X/* external data objects used by this driver */
- Xextern int tthiwat [];
- X
- X/* the following stuff is defined in space.c */
- Xextern uint fas_physical_units;
- Xextern ulong fas_port [];
- Xextern uint fas_vec [];
- Xextern uint fas_init_seq [];
- Xextern uint fas_mcb [];
- Xextern ulong fas_modem [];
- Xextern ulong fas_flow [];
- Xextern uint fas_ctl_port [];
- Xextern uint fas_ctl_val [];
- Xextern uint fas_int_ack_port [];
- Xextern uint fas_int_ack [];
- Xextern struct fas_info fas_info [];
- Xextern struct tty fas_tty [];
- Xextern struct fas_info *fas_info_ptr [];
- Xextern struct tty *fas_tty_ptr [];
- X/* end of space.c references */
- X
- X#if defined(FASI)
- Xint fasiintr_entries = 0;
- Xextern char *fasi_space_ident;
- X#endif /* FASI */
- X
- X/* fas_is_initted
- X Flag to indicate that we have been thru init.
- X This is realy only necessary for systems that use asyputchar
- X and asygetchar but it doesn't hurt to have it anyway.
- X*/
- Xstatic int fas_is_initted = FALSE;
- X
- X/* event_scheduled
- X Flag to indicate that the event handler has been scheduled
- X via the timeout() function.
- X*/
- Xstatic int event_scheduled = FALSE;
- X
- X/* array of pointers to the first fas_info structure for each
- X interrupt vector
- X*/
- Xstatic struct fas_info *fas_first_int_user [NUM_INT_VECTORS];
- X
- X/* the values for the various baud rates */
- Xstatic uint fas_speeds [CBAUD + 1] =
- X{ 1, BAUD_BASE/50,
- X BAUD_BASE/75, BAUD_BASE/110,
- X (2*BAUD_BASE+134)/269, BAUD_BASE/150,
- X BAUD_BASE/200, BAUD_BASE/300,
- X BAUD_BASE/600, BAUD_BASE/1200,
- X BAUD_BASE/1800, BAUD_BASE/2400,
- X BAUD_BASE/4800, BAUD_BASE/9600,
- X BAUD_BASE/19200, BAUD_BASE/38400
- X};
- X
- X/* time for one character to completely leave the transmitter shift register */
- Xstatic uint fas_ctimes [CBAUD + 1] =
- X{ 1, HZ*15/50+2,
- X HZ*15/75+2, HZ*15/110+2,
- X HZ*30/269+2, HZ*15/150+2,
- X HZ*15/200+2, HZ*15/300+2,
- X HZ*15/600+2, HZ*15/1200+2,
- X HZ*15/1800+2, HZ*15/2400+2,
- X HZ*15/4800+2, HZ*15/9600+2,
- X HZ*15/19200+2, HZ*15/38400+2
- X};
- X
- X/* dynamically adapt xmit buffer size to baud rate to prevent long buffer
- X drains at low speeds
- X These values are checked against boundaries and will be modified if
- X necessary before use. Checking is done in fas_param (). Drain time
- X is about 5 seconds with continuous character flow.
- X*/
- Xstatic uint fas_xbuf_size [CBAUD + 1] =
- X{ 1, 50/2,
- X 75/2, 110/2,
- X 269/4, 150/2,
- X 200/2, 300/2,
- X 600/2, 1200/2,
- X 1800/2, 2400/2,
- X 4800/2, 9600/2,
- X 19200/2, 38400/2
- X};
- X
- X/* lookup table for minor device number -> open mode flags translation */
- Xstatic uint fas_open_modes [16] =
- X{
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL | OS_HWO_HANDSHAKE
- X | OS_HWI_HANDSHAKE,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL | OS_HWO_HANDSHAKE,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_CLOCAL | OS_HWO_HANDSHAKE
- X | OS_HDX_HANDSHAKE,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_HWO_HANDSHAKE
- X | OS_HWI_HANDSHAKE,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_HWO_HANDSHAKE,
- X OS_OPEN_FOR_DIALOUT | OS_FAKE_CARR_ON | OS_HWO_HANDSHAKE
- X | OS_HDX_HANDSHAKE,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT | OS_HWO_HANDSHAKE
- X | OS_HWI_HANDSHAKE,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT | OS_HWO_HANDSHAKE,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_NO_DIALOUT | OS_HWO_HANDSHAKE
- X | OS_HDX_HANDSHAKE,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_HWO_HANDSHAKE
- X | OS_HWI_HANDSHAKE,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_HWO_HANDSHAKE,
- X OS_OPEN_FOR_GETTY | OS_WAIT_OPEN | OS_HWO_HANDSHAKE
- X | OS_HDX_HANDSHAKE
- X};
- X
- X/* The following defines are used to access multiplexed ports. */
- X#define GET_PORT(port,num) \
- X ((fip->device_flags.i & DF_CTL_EVERY)\
- X ? (port)\
- X : (port) + (num))
- X
- X#define fas_first_ctl(fip,port) \
- X ((void) (((fip)->device_flags.i & DF_CTL_FIRST)\
- X ? outb (CTL_PORT, (port).p.ctl)\
- X : 0))
- X
- X#define fas_ctl(fip,port) \
- X ((void) (((fip)->device_flags.i & (DF_CTL_FIRST | DF_CTL_EVERY))\
- X ? outb (CTL_PORT, (port).p.ctl)\
- X : 0))
- X
- X#define fas_first_outb(fip,port,val) \
- X ((void) (((fip)->device_flags.i & (DF_CTL_FIRST | DF_CTL_EVERY))\
- X ? outb (CTL_PORT, (port).p.ctl)\
- X : 0),\
- X (void) outb ((port).addr, (val)))
- X
- X#define fas_outb(fip,port,val) \
- X ((void) (((fip)->device_flags.i & DF_CTL_EVERY)\
- X ? outb (CTL_PORT, (port).p.ctl)\
- X : 0),\
- X (void) outb ((port).addr, (val)))
- X
- X#define fas_first_inb(fip,port) \
- X ((void) (((fip)->device_flags.i & (DF_CTL_FIRST | DF_CTL_EVERY))\
- X ? outb (CTL_PORT, (port).p.ctl)\
- X : 0),\
- X inb ((port).addr))
- X
- X#define fas_inb(fip,port) \
- X ((void) (((fip)->device_flags.i & DF_CTL_EVERY)\
- X ? outb (CTL_PORT, (port).p.ctl)\
- X : 0),\
- X inb ((port).addr))
- X
- X/* The following defines are used to take apart the minor device numbers. */
- X#define GET_UNIT(dev) ((dev) & 0x0f)
- X#define GET_OPEN_MODE(dev) (fas_open_modes [((dev) >> 4) & 0x0f])
- X
- X/* lock device against concurrent use */
- X#define get_device_lock(fip,prio) \
- X{\
- X /* sleep while device is used by an other process */\
- X while ((fip)->device_flags.i & DF_DEVICE_LOCKED)\
- X (void) sleep ((caddr_t) &(fip)->device_flags.i, (prio));\
- X (fip)->device_flags.s |= DF_DEVICE_LOCKED;\
- X}
- X
- X/* release device */
- X#define release_device_lock(fip) \
- X{\
- X (fip)->device_flags.s &= ~DF_DEVICE_LOCKED;\
- X /* wakeup the process that may wait for this device */\
- X (void) wakeup ((caddr_t) &(fip)->device_flags.i);\
- X}
- X
- X/* schedule event */
- X#define event_sched(fip,event) \
- X{\
- X (fip)->event_flags.s |= (event);\
- X if (!event_scheduled)\
- X {\
- X event_scheduled = TRUE;\
- X (void) timeout (fas_event, (void *) NULL,\
- X (EVENT_TIME) * (HZ) / 1000);\
- X }\
- X}
- X
- X/* fasinit
- X This routine checks for the presense of the devices in the fas_port
- X array and if the device is present tests and initializes it.
- X During the initialization if the device is determined to be an
- X NS16550A chip the DF_DEVICE_IS_NS16550A flag is set and the FIFOs will
- X be used. If the device is an i82510 chip the DF_DEVICE_IS_I82510 flag
- X is set and the device will be handled accordingly.
- X*/
- X
- Xint
- Xfasinit ()
- X{
- X register struct fas_info *fip;
- X register uint unit;
- X uint logical_units, port, *seq_ptr;
- X char port_stat [MAX_UNITS + 1];
- X REGVAR;
- X
- X if (fas_is_initted)
- X return (0);
- X
- X fas_is_initted = TRUE;
- X
- X /* execute the init sequence for the serial card */
- X for (seq_ptr = fas_init_seq; *seq_ptr; seq_ptr++)
- X {
- X port = *seq_ptr;
- X seq_ptr++;
- X if (*seq_ptr & READ_PORT)
- X (void) inb (port);
- X else
- X (void) outb (port, *seq_ptr);
- X }
- X
- X /* setup the list of pointers to the tty structures */
- X for (unit = 0, logical_units = fas_physical_units * 2;
- X unit < logical_units; unit++)
- X fas_tty_ptr [unit] = &fas_tty [unit];
- X
- X /* setup and initialize all serial ports */
- X for (unit = 0; unit < fas_physical_units; unit++)
- X {
- X fas_info_ptr [unit] = fip = &fas_info [unit];
- X port_stat [unit] = '-';
- X if (port = (uint) ((ushort) (fas_port [unit])))
- X {
- X /* check the int vector */
- X if (fas_vec [unit] >= NUM_INT_VECTORS)
- X {
- X port_stat [unit] = '>';
- X continue;
- X }
- X
- X /* init all of its ports */
- X if (fas_ctl_port [unit])
- X {
- X fip->ctl_port = fas_ctl_port [unit];
- X
- X if (fas_ctl_val [unit] & 0xff00)
- X fip->device_flags.s |= DF_CTL_EVERY;
- X else
- X fip->device_flags.s |= DF_CTL_FIRST;
- X }
- X
- X fip->port_0.p.addr = GET_PORT (port, 0);
- X fip->port_1.p.addr = GET_PORT (port, 1);
- X fip->port_2.p.addr = GET_PORT (port, 2);
- X fip->port_3.p.addr = GET_PORT (port, 3);
- X fip->port_4.p.addr = GET_PORT (port, 4);
- X fip->port_5.p.addr = GET_PORT (port, 5);
- X fip->port_6.p.addr = GET_PORT (port, 6);
- X fip->port_0.p.ctl = fas_make_ctl_val (fip, unit, 0);
- X fip->port_1.p.ctl = fas_make_ctl_val (fip, unit, 1);
- X fip->port_2.p.ctl = fas_make_ctl_val (fip, unit, 2);
- X fip->port_3.p.ctl = fas_make_ctl_val (fip, unit, 3);
- X fip->port_4.p.ctl = fas_make_ctl_val (fip, unit, 4);
- X fip->port_5.p.ctl = fas_make_ctl_val (fip, unit, 5);
- X fip->port_6.p.ctl = fas_make_ctl_val (fip, unit, 6);
- X fip->vec = fas_vec [unit];
- X fip->modem.l = fas_modem [unit];
- X fip->flow.l = fas_flow [unit];
- X
- X /* mask off invalid bits */
- X fip->modem.m.di &= MC_ANY_CONTROL;
- X fip->modem.m.eo &= MC_ANY_CONTROL;
- X fip->modem.m.ei &= MC_ANY_CONTROL;
- X fip->modem.m.ca &= MS_ANY_PRESENT;
- X fip->flow.m.ic &= MC_ANY_CONTROL;
- X fip->flow.m.oc &= MS_ANY_PRESENT;
- X fip->flow.m.oe &= MS_ANY_PRESENT;
- X fip->flow.m.hc &= MC_ANY_CONTROL;
- X
- X fip->recv_ring_put_ptr = fip->recv_buffer;
- X fip->recv_ring_take_ptr = fip->recv_buffer;
- X fip->xmit_ring_put_ptr = fip->xmit_buffer;
- X fip->xmit_ring_take_ptr = fip->xmit_buffer;
- X fip->xmit_fifo_size = 1;
- X
- X fip->ier = IE_NONE; /* disable all ints */
- X fas_first_outb (fip, INT_ENABLE_PORT, fip->ier);
- X
- X /* is there a serial chip ? */
- X if (fas_inb (fip, INT_ENABLE_PORT) != fip->ier)
- X {
- X port_stat [unit] = '?';
- X continue; /* a hardware error */
- X }
- X
- X /* test the chip thoroughly */
- X if ((port_stat [unit] = (fas_test_device (fip) + '0'))
- X != '0')
- X {
- X continue; /* a hardware error */
- X }
- X
- X fip->lcr = 0;
- X fas_outb (fip, LINE_CTL_PORT, fip->lcr);
- X fip->mcr = fas_mcb [unit] | fip->modem.m.di;
- X fas_outb (fip, MDM_CTL_PORT, fip->mcr);
- X
- X port_stat [unit] = '*';
- X
- X /* let's see if it's an NS16550A */
- X fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_INIT_CMD);
- X if (!(~fas_inb (fip, INT_ID_PORT) & II_NS_FIFO_ENABLED))
- X {
- X fip->device_flags.s |= DF_DEVICE_IS_NS16550A;
- X fip->xmit_fifo_size = OUTPUT_NS_FIFO_SIZE;
- X port_stat [unit] = 'F';
- X fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
- X }
- X else
- X {
- X fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
- X /* or is it an i82510 ? */
- X fas_outb (fip, I_BANK_PORT, I_BANK_2);
- X if (!(~fas_inb (fip, I_BANK_PORT) & I_BANK_2))
- X {
- X fip->device_flags.s |= DF_DEVICE_IS_I82510;
- X fip->xmit_fifo_size = OUTPUT_I_FIFO_SIZE;
- X port_stat [unit] = 'f';
- X fas_outb (fip, I_BANK_PORT, I_BANK_1);
- X fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
- X fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
- X }
- X fas_outb (fip, I_BANK_PORT, I_BANK_0);
- X }
- X
- X /* disable FIFOs if requested in space.c */
- X if ((fas_port [unit] & NO_FIFO) && (fip->device_flags.i
- X & (DF_DEVICE_IS_NS16550A
- X | DF_DEVICE_IS_I82510)))
- X {
- X fip->device_flags.s &= ~(DF_DEVICE_IS_NS16550A
- X | DF_DEVICE_IS_I82510);
- X fip->xmit_fifo_size = 1;
- X port_stat [unit] = '+';
- X }
- X
- X /* clear potential interrupts */
- X (void) fas_inb (fip, MDM_STATUS_PORT);
- X (void) fas_inb (fip, RCV_DATA_PORT);
- X (void) fas_inb (fip, RCV_DATA_PORT);
- X (void) fas_inb (fip, LINE_STATUS_PORT);
- X (void) fas_inb (fip, INT_ID_PORT);
- X if (port = fas_int_ack_port [fip->vec])
- X (void) outb (port, fas_int_ack [fip->vec]);
- X
- X /* show that it is present and configured */
- X fip->device_flags.s |= DF_DEVICE_CONFIGURED;
- X }
- X }
- X
- X#if defined (NEED_PUT_GETCHAR)
- X fip = &fas_info [0];
- X fip->mcr &= ~fip->modem.m.di;
- X fip->mcr |= INITIAL_MDM_CONTROL;
- X fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
- X
- X fip->lcr = INITIAL_LINE_CONTROL;
- X fas_outb (fip, LINE_CTL_PORT, fip->lcr | LC_ENABLE_DIVISOR);
- X fas_outb (fip, DIVISOR_LSB_PORT, INITIAL_BAUD_RATE);
- X fas_outb (fip, DIVISOR_MSB_PORT, (INITIAL_BAUD_RATE) >> 8);
- X fas_outb (fip, LINE_CTL_PORT, fip->lcr);
- X#endif
- X
- X#if defined (SCO) || defined (XENIX)
- X for (unit = 0; unit < fas_physical_units; unit++)
- X (void) printcfg ("fas", (uint) ((ushort) (fas_port [unit])), 7,
- X fas_vec [unit], -1,
- X#if defined (FASI)
- X "unit=%d type=%c FAS/i 2.08.01",
- X#else
- X "unit=%d type=%c release=2.08.0",
- X#endif /* FASI */
- X unit, port_stat [unit]);
- X#else
- X port_stat [unit] = '\0';
- X (void) printf ("\nFAS 2.08.0 async driver: Unit 0-%d init state is [%s]\n\n",
- X unit - 1,
- X port_stat);
- X#endif
- X return (0);
- X}
- X
- X/* Open a tty line. This function is called for every open, as opposed
- X to the fasclose function which is called only with the last close.
- X*/
- Xint
- Xfasopen (dev, flag)
- Xint dev;
- Xint flag;
- X{
- X register struct fas_info *fip;
- X register struct tty *ttyp;
- X register uint open_mode;
- X uint physical_unit;
- X int old_level;
- X
- X physical_unit = GET_UNIT (dev);
- X
- X /* check for valid port number */
- X if (physical_unit >= fas_physical_units)
- X {
- X u.u_error = ENXIO;
- X return (-1);
- X }
- X
- X fip = fas_info_ptr [physical_unit];
- X
- X /* was the port present at init time ? */
- X if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))
- X {
- X u.u_error = ENXIO;
- X return (-1);
- X }
- X
- X open_mode = GET_OPEN_MODE (dev);
- X
- X old_level = SPLINT ();
- X get_device_lock (fip, TTIPRI);
- X
- X /* If this is a getty open, the device is already open for
- X dialout and the FNDELAY flag is not set, wait until device
- X is closed.
- X */
- X while ((open_mode & OS_OPEN_FOR_GETTY)
- X && (fip->o_state & OS_OPEN_FOR_DIALOUT)
- X && !(flag & FNDELAY))
- X {
- X release_device_lock (fip);
- X (void) sleep ((caddr_t) &fip->o_state, TTIPRI);
- X get_device_lock (fip, TTIPRI);
- X }
- X
- X /* If the device is already open and another open uses a different
- X open mode or if a getty open waits for carrier and doesn't allow
- X parallel dialout opens, return with EBUSY error.
- X */
- X if ((fip->o_state & ((open_mode & OS_OPEN_FOR_GETTY)
- X ? (OS_OPEN_STATES | OS_WAIT_OPEN)
- X : (OS_OPEN_STATES | OS_NO_DIALOUT)))
- X && ((flag & FEXCL)
- X || ((open_mode ^ fip->o_state) & (u.u_uid
- X ? OS_TEST_MASK
- X : OS_SU_TEST_MASK))))
- X {
- X u.u_error = EBUSY;
- X release_device_lock (fip);
- X (void) splx (old_level);
- X return (-1);
- X }
- X
- X /* disable subsequent opens */
- X if (flag & FEXCL)
- X open_mode |= OS_EXCLUSIVE_OPEN_1;
- X
- X /* set up pointer to tty structure */
- X ttyp = (open_mode & OS_OPEN_FOR_GETTY)
- X ? fas_tty_ptr [physical_unit + fas_physical_units]
- X : fas_tty_ptr [physical_unit];
- X
- X /* things to do on first open only */
- X if (!(fip->o_state & ((open_mode & OS_OPEN_FOR_GETTY)
- X ? (OS_OPEN_STATES | OS_WAIT_OPEN)
- X : OS_OPEN_STATES)))
- X {
- X /* init data structures */
- X fip->tty = ttyp;
- X (void) ttinit (ttyp);
- X ttyp->t_proc = fas_proc;
- X fip->po_state = fip->o_state;
- X fip->o_state = open_mode & ~OS_OPEN_STATES;
- X#if defined (HAVE_VPIX)
- X /* initialize VP/ix related variables */
- X fip->v86_proc = (v86_t *) NULL;
- X fip->v86_intmask = 0;
- X fip->v86_ss.ss_start = CSTART;
- X fip->v86_ss.ss_stop = CSTOP;
- X#endif
- X fas_open_device (fip); /* open physical device */
- X fas_param (fip, HARD_INIT); /* set up port registers */
- X
- X /* allow pending tty interrupts */
- X (void) SPLWRK ();
- X (void) SPLINT ();
- X }
- X
- X /* If getty open and the FNDELAY flag is not set,
- X block and wait for carrier if device not yet open.
- X */
- X if ((open_mode & OS_OPEN_FOR_GETTY) && !(flag & FNDELAY))
- X {
- X /* sleep while open for dialout or no carrier */
- X while ((fip->o_state & OS_OPEN_FOR_DIALOUT)
- X || !(ttyp->t_state & (ISOPEN | CARR_ON)))
- X {
- X ttyp->t_state |= WOPEN;
- X release_device_lock (fip);
- X (void) sleep ((caddr_t) &ttyp->t_canq, TTIPRI);
- X get_device_lock (fip, TTIPRI);
- X }
- X ttyp->t_state &= ~WOPEN;
- X }
- X
- X /* wakeup processes that are still sleeping in getty open */
- X if (ttyp->t_state & WOPEN)
- X#if defined(FASI)
- X {
- X#endif
- X (void) wakeup ((caddr_t) &ttyp->t_canq);
- X#if defined(FASI)
- X (void) wakeup ((caddr_t) &fip->device_flags.i);
- X }
- X#endif
- X
- X /* we need to flush the receiver with the first open */
- X if (!(fip->o_state & OS_OPEN_STATES))
- X fas_cmd (fip, ttyp, T_RFLUSH);
- X
- X (*linesw [ttyp->t_line].l_open) (ttyp);
- X
- X /* set open type flags */
- X fip->o_state = open_mode;
- X
- X release_device_lock (fip);
- X (void) splx (old_level);
- X return (0);
- X}
- X
- X/* Close a tty line. This is only called if there is no other
- X concurrent open left. A blocked getty open is not counted as
- X a concurrent open because in this state it isn't really open.
- X*/
- Xint
- Xfasclose (dev)
- Xint dev;
- X{
- X register struct fas_info *fip;
- X register struct tty *ttyp;
- X uint physical_unit;
- X uint open_mode;
- X int old_level;
- X void (*old_sigkill)();
- X
- X physical_unit = GET_UNIT (dev);
- X
- X fip = fas_info_ptr [physical_unit];
- X
- X open_mode = GET_OPEN_MODE (dev);
- X
- X /* set up pointer to tty structure */
- X ttyp = (open_mode & OS_OPEN_FOR_GETTY)
- X ? fas_tty_ptr [physical_unit + fas_physical_units]
- X : fas_tty_ptr [physical_unit];
- X
- X old_level = SPLINT ();
- X get_device_lock (fip, TTIPRI);
- X
- X /* wait for output buffer drain only if device was open */
- X if (ttyp->t_state & ISOPEN)
- X {
- X /* flush the output buffer immediately if the device
- X has been shut down because of an error
- X */
- X if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))
- X {
- X (void) ttyflush (ttyp, FWRITE);
- X }
- X /* wait for buffer drain and catch interrupts */
- X while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))
- X {
- X old_sigkill = u.u_signal [SIGKILL - 1];
- X /* allow kill signal if close on exit */
- X if (old_sigkill == SIG_IGN)
- X u.u_signal [SIGKILL - 1] = SIG_DFL;
- X ttyp->t_state |= TTIOW;
- X if (sleep ((caddr_t) &ttyp->t_oflag, TTOPRI | PCATCH))
- X {
- X /* caught signal */
- X ttyp->t_state &= ~TTIOW;
- X /* If close on exit, flush output buffer to
- X allow completion of the fasclose() function.
- X Otherwise, do the normal signal handling.
- X */
- X if (old_sigkill == SIG_IGN)
- X (void) ttyflush (ttyp, FWRITE);
- X else
- X {
- X release_device_lock (fip);
- X (void) splx (old_level);
- X longjmp (u.u_qsav);
- X }
- X }
- X if (old_sigkill == SIG_IGN)
- X u.u_signal [SIGKILL - 1] = old_sigkill;
- X }
- X }
- X
- X (*linesw [ttyp->t_line].l_close) (ttyp);
- X
- X /* allow pending tty interrupts */
- X (void) SPLWRK ();
- X (void) SPLINT ();
- X
- X if (open_mode & OS_OPEN_FOR_GETTY)
- X {
- X /* not waiting any more */
- X ttyp->t_state &= ~WOPEN;
- X if (!(fip->o_state & OS_OPEN_FOR_DIALOUT))
- X {
- X fas_close_device (fip);
- X fip->o_state = OS_DEVICE_CLOSED;
- X }
- X else
- X fip->po_state = OS_DEVICE_CLOSED;
- X }
- X else
- X {
- X fas_close_device (fip);
- X fip->o_state = OS_DEVICE_CLOSED;
- X /* If there is a waiting getty open on
- X this port, reopen the physical device.
- X */
- X if (fip->po_state & OS_WAIT_OPEN)
- X {
- X /* get the getty version of the
- X tty structure
- X */
- X fip->tty = fas_tty_ptr [physical_unit
- X + fas_physical_units];
- X fip->o_state = fip->po_state;
- X fip->po_state = OS_DEVICE_CLOSED;
- X#if defined (HAVE_VPIX)
- X /* initialize VP/ix related variables */
- X fip->v86_proc = (v86_t *) NULL;
- X fip->v86_intmask = 0;
- X fip->v86_ss.ss_start = CSTART;
- X fip->v86_ss.ss_stop = CSTOP;
- X#endif
- X if (!(fip->device_flags.i & DF_DO_HANGUP))
- X {
- X fas_open_device (fip);
- X /* set up port registers */
- X fas_param (fip, HARD_INIT);
- X }
- X }
- X (void) wakeup ((caddr_t) &fip->o_state);
- X }
- X
- X if (!(fip->device_flags.i & DF_DO_HANGUP))
- X release_device_lock (fip);
- X
- X#if defined(FASI)
- X (void)wakeup((caddr_t)&fip->device_flags.i);
- X#endif
- X (void) splx (old_level);
- X return (0);
- X}
- X
- X/* read characters from the input buffer */
- Xint
- Xfasread (dev)
- Xint dev;
- X{
- X register struct fas_info *fip;
- X register struct tty *ttyp;
- X int old_level;
- X
- X fip = fas_info_ptr [GET_UNIT (dev)];
- X
- X /* was the port present at init time ? */
- X if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))
- X {
- X u.u_error = ENXIO;
- X return (-1);
- X }
- X
- X ttyp = fip->tty;
- X
- X (*linesw [ttyp->t_line].l_read) (ttyp);
- X
- X old_level = SPLINT ();
- X
- X /* schedule character transfer to UNIX buffer */
- X if (fip->recv_ring_cnt
- X#if defined (HAVE_VPIX)
- X && (((fip->iflag & DOSMODE)
- X ? MAX_VPIX_FILL - MIN_READ_CHUNK
- X : MAX_UNIX_FILL - MIN_READ_CHUNK)
- X >= ttyp->t_rawq.c_cc)
- X#else
- X && ((MAX_UNIX_FILL - MIN_READ_CHUNK) >= ttyp->t_rawq.c_cc)
- X#endif
- X && !(fip->flow_flags.i & FF_RXFER_STOPPED))
- X {
- X event_sched (fip, EF_DO_RXFER);
- X }
- X
- X#if defined(FASI)
- X (void)wakeup((caddr_t)&fip->device_flags.i);
- X#endif
- X (void) splx (old_level);
- X return (0);
- X}
- X
- X/* write characters to the output buffer */
- Xint
- Xfaswrite (dev)
- Xint dev;
- X{
- X register struct fas_info *fip;
- X register struct tty *ttyp;
- X
- X fip = fas_info_ptr [GET_UNIT (dev)];
- X
- X /* was the port present at init time ? */
- X if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))
- X {
- X u.u_error = ENXIO;
- X return (-1);
- X }
- X
- X ttyp = fip->tty;
- X
- X (*linesw [ttyp->t_line].l_write) (ttyp);
- X return (0);
- X}
- X
- X/*+-------------------------------------------------------------------------
- X strlen(str)
- X--------------------------------------------------------------------------*/
- X#if defined(FASI)
- Xstatic int
- Xstrlen(str)
- Xregister char *str;
- X{
- Xregister len = 0;
- X while(*str++)
- X len++;
- X return(len);
- X} /* end of strlen */
- X#endif /* FASI */
- X
- X/* process ioctl calls */
- Xint
- Xfasioctl (dev, cmd, arg3, arg4)
- Xint dev;
- Xint cmd;
- Xunion ioctl_arg arg3;
- Xint arg4;
- X{
- X register struct fas_info *fip;
- X register struct tty *ttyp;
- X int v86_cmd, v86_data;
- X int old_level;
- X REGVAR;
- X
- X fip = fas_info_ptr [GET_UNIT (dev)];
- X
- X /* was the port present at init time ? */
- X if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))
- X {
- X u.u_error = ENXIO;
- X return (-1);
- X }
- X
- X ttyp = fip->tty;
- X
- X /* process ioctl commands */
- X switch (cmd)
- X {
- X#if defined (FASI)
- X case FASIC_SIP_CHANGE:
- X (void) sleep ((caddr_t) &fip->device_flags.i, PZERO + 1);
- X case FASIC_SIP:
- X if(copyout((char *)fip,arg3.cparg,sizeof(*fip)))
- X {
- X u.u_error = EFAULT;
- X return(-1);
- X }
- X return(fasiintr_entries);
- X case FASIC_DVR_IDENT:
- X if(copyout(fasi_driver_ident,arg3.cparg,
- X strlen(fasi_driver_ident) + 1))
- X {
- X u.u_error = EFAULT;
- X return(-1);
- X }
- X break;
- X case FASIC_SPACE_IDENT:
- X if(copyout(fasi_space_ident,arg3.cparg,
- X strlen(fasi_space_ident) + 1))
- X {
- X u.u_error = EFAULT;
- X return(-1);
- X }
- X break;
- X case FASIC_MSR:
- X return((unsigned int)fip->msr);
- X case FASIC_LCR:
- X return((unsigned int)fip->lcr);
- X case FASIC_IER:
- X return((unsigned int)fip->ier);
- X case FASIC_MCR:
- X return((unsigned int)fip->mcr);
- X case FASIC_RESET_STAT:
- X old_level = SPLINT();
- X fip->characters_received = 0;
- X fip->characters_transmitted = 0;
- X fip->modem_status_events = 0;
- X fip->overrun_errors = 0;
- X fip->framing_errors = 0;
- X fip->parity_errors = 0;
- X fip->rings_detected = 0;
- X fip->breaks_detected = 0;
- X fip->xmtr_hw_flow_count = 0;
- X fip->xmtr_sw_flow_count = 0;
- X fip->rcvr_hw_flow_count = 0;
- X fip->rcvr_sw_flow_count = 0;
- X (void)splx(old_level);
- X break;
- X#endif /* FASI */
- X#if defined (HAVE_VPIX)
- X case AIOCINTTYPE: /* set pseudorupt type */
- X switch (arg3.iarg)
- X {
- X case V86VI_KBD:
- X case V86VI_SERIAL0:
- X case V86VI_SERIAL1:
- X intr_disable ();
- X fip->v86_intmask = arg3.iarg;
- X intr_restore ();
- X break;
- X
- X default:
- X intr_disable ();
- X fip->v86_intmask = V86VI_SERIAL0;
- X intr_restore ();
- X break;
- X }
- X break;
- X
- X case AIOCDOSMODE: /* enable dos mode */
- X if (!(fip->iflag & DOSMODE))
- X {
- X old_level = SPLINT ();
- X fip->v86_proc = u.u_procp->p_v86;
- X if (!(fip->v86_intmask))
- X fip->v86_intmask = V86VI_SERIAL0;
- X ttyp->t_iflag |= DOSMODE;
- X if (fip->v86_intmask != V86VI_KBD)
- X ttyp->t_cflag |= CLOCAL;
- X fas_param (fip, SOFT_INIT);
- X (void) splx (old_level);
- X }
- X u.u_r.r_reg.r_val1 = 0;
- X break;
- X
- X case AIOCNONDOSMODE: /* disable dos mode */
- X if (fip->iflag & DOSMODE)
- X {
- X old_level = SPLINT ();
- X fip->v86_proc = (v86_t *) NULL;
- X fip->v86_intmask = 0;
- X ttyp->t_iflag &= ~DOSMODE;
- X if (fip->flow_flags.i & FF_RXFER_STOPPED)
- X {
- X fip->flow_flags.s &= ~FF_RXFER_STOPPED;
- X /* schedule character transfer
- X to UNIX buffer
- X */
- X if (fip->recv_ring_cnt)
- X event_sched (fip, EF_DO_RXFER);
- X }
- X fip->lcr &= ~LC_SET_BREAK_LEVEL;
- X fas_param (fip, HARD_INIT);
- X (void) splx (old_level);
- X }
- X u.u_r.r_reg.r_val1 = 0;
- X break;
- X
- X case AIOCSERIALOUT: /* setup port registers for dos */
- X if ((fip->iflag & DOSMODE) && fip->v86_proc)
- X {
- X /* wait until output is done */
- X old_level = SPLINT ();
- X while (ttyp->t_outq.c_cc
- X || (ttyp->t_state & (BUSY | TIMEOUT)))
- X {
- X ttyp->t_state |= TTIOW;
- X (void) sleep ((caddr_t) &ttyp->t_oflag,
- X TTOPRI);
- X }
- X
- X /* block transmitter and wait until it is
- X empty
- X */
- X fip->device_flags.s |= DF_XMIT_LOCKED;
- X while (fip->device_flags.i & (DF_XMIT_BUSY
- X | DF_XMIT_BREAK
- X | DF_GUARD_TIMEOUT))
- X (void) sleep ((caddr_t) &fip->
- X device_flags.i,
- X PZERO - 1);
- X (void) splx (old_level);
- X
- X /* get port write command */
- X v86_cmd = fubyte (arg3.cparg);
- X /* set divisor lsb requested */
- X if (v86_cmd & SIO_MASK(SO_DIVLLSB))
- X {
- X v86_data = fubyte (arg3.cparg
- X + SO_DIVLLSB);
- X intr_disable ();
- X fas_first_outb (fip, LINE_CTL_PORT, fip->lcr
- X | LC_ENABLE_DIVISOR);
- X fas_outb (fip, DIVISOR_LSB_PORT, v86_data);
- X fas_outb (fip, LINE_CTL_PORT, fip->lcr
- X & ~LC_ENABLE_DIVISOR);
- X intr_restore ();
- X }
- X /* set divisor msb requested */
- X if (v86_cmd & SIO_MASK(SO_DIVLMSB))
- X {
- X v86_data = fubyte (arg3.cparg
- X + SO_DIVLMSB);
- X intr_disable ();
- X fas_first_outb (fip, LINE_CTL_PORT, fip->lcr
- X | LC_ENABLE_DIVISOR);
- X fas_outb (fip, DIVISOR_MSB_PORT, v86_data);
- X fas_outb (fip, LINE_CTL_PORT, fip->lcr
- X & ~LC_ENABLE_DIVISOR);
- X intr_restore ();
- X }
- X /* set lcr requested */
- X if (v86_cmd & SIO_MASK(SO_LCR))
- X {
- X v86_data = fubyte (arg3.cparg + SO_LCR);
- X intr_disable ();
- X fip->lcr = v86_data
- X & ~LC_ENABLE_DIVISOR;
- X fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
- X intr_restore ();
- X }
- X /* set mcr requested */
- X if (v86_cmd & SIO_MASK(SO_MCR))
- X {
- X v86_data = fubyte (arg3.cparg + SO_MCR);
- X old_level = SPLINT ();
- X /* virtual dtr processing */
- X if (v86_data & MC_SET_DTR)
- X {
- X fip->device_flags.s
- X |= DF_MODEM_ENABLED;
- X fip->mcr |= (fip->o_state
- X & OS_WAIT_OPEN)
- X ? fip->modem.m.ei
- X : fip->modem.m.eo;
- X }
- X else
- X {
- X fip->device_flags.s
- X &= ~DF_MODEM_ENABLED;
- X fip->mcr &= (fip->o_state
- X & OS_WAIT_OPEN)
- X ? ~fip->modem.m.ei
- X : ~fip->modem.m.eo;
- X }
- X /* virtual rts processing */
- X if (fip->flow_flags.i
- X & FF_HWI_HANDSHAKE)
- X {
- X if (v86_data & MC_SET_RTS)
- X {
- X if (fip->flow_flags.i
- X & FF_RXFER_STOPPED)
- X {
- X fip->flow_flags.s
- X &= ~FF_RXFER_STOPPED;
- X /* schedule character transfer
- X to UNIX buffer
- X */
- X if (fip->recv_ring_cnt)
- X event_sched (fip,
- X EF_DO_RXFER);
- X }
- X }
- X else
- X fip->flow_flags.s
- X |= FF_RXFER_STOPPED;
- X }
- X else if (!(fip->flow_flags.i
- X & FF_HDX_HANDSHAKE))
- X {
- X if (v86_data & MC_SET_RTS)
- X {
- X fip->flow_flags.s
- X |= FF_HDX_STARTED;
- X fip->mcr
- X |= fip->flow.m.hc;
- X }
- X else
- X {
- X fip->flow_flags.s
- X &= ~FF_HDX_STARTED;
- X fip->mcr
- X &= ~fip->flow.m.hc;
- X }
- X }
- X fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
- X (void) splx (old_level);
- X }
- X
- X old_level = SPLINT ();
- X /* enable transmitter and restart output */
- X fip->device_flags.s &= ~DF_XMIT_LOCKED;
- X fas_xproc (fip);
- X (void) splx (old_level);
- X }
- X break;
- X
- X case AIOCSERIALIN: /* read port registers for dos */
- X if ((fip->iflag & DOSMODE) && fip->v86_proc)
- X {
- X v86_cmd = fubyte (arg3.cparg);
- X if (v86_cmd & SIO_MASK(SI_MSR))
- X {
- X (void) subyte (arg3.cparg + SI_MSR,
- X ((fip->flow_flags.i
- X & FF_HWO_HANDSHAKE)
- X ? fip->msr
- X | fip->flow.m.oc
- X | fip->flow.m.oe
- X : fip->msr)
- X & MS_ANY_PRESENT);
- X }
- X }
- X break;
- X
- X case AIOCSETSS: /* set start/stop characters */
- X intr_disable ();
- X *((short *) (&fip->v86_ss)) = arg3.iarg;
- X intr_restore ();
- X break;
- X
- X case AIOCINFO: /* show what type of device we are */
- X u.u_r.r_reg.r_val1 = ('a' << 8) | (uint) ((unchar) dev);
- X break;
- X#endif
- X default: /* default ioctl processing */
- X /* if it is a TCSETA* command, call fas_param () */
- X if (ttiocom (ttyp, cmd, arg3, arg4))
- X {
- X old_level = SPLINT ();
- X fas_param (fip, SOFT_INIT);
- X (void) splx (old_level);
- X }
- X break;
- X }
- X return (0);
- X}
- X
- X/* pass fas commands to the fas multi-function procedure */
- Xstatic int
- Xfas_proc (ttyp, arg2)
- Xstruct tty *ttyp;
- Xint arg2;
- X{
- X register uint physical_unit;
- X int old_level;
- X
- X physical_unit = ttyp - &fas_tty [0];
- X if (physical_unit >= fas_physical_units)
- X physical_unit -= fas_physical_units;
- X
- X old_level = SPLINT ();
- X fas_cmd (fas_info_ptr [physical_unit], ttyp, arg2);
- X (void) splx (old_level);
- X return (0);
- X}
- X
- X/* set up a port according to the given termio structure */
- Xstatic void
- Xfas_param (fip, init_type)
- Xregister struct fas_info *fip;
- Xint init_type;
- X{
- X register uint cflag;
- X uint divisor;
- X int xmit_ring_size;
- X REGVAR;
- X
- X cflag = fip->tty->t_cflag;
- X
- X#if defined (HAVE_VPIX)
- X /* we don't set port registers if we are in dos mode */
- X if (fip->tty->t_iflag & DOSMODE)
- X goto setflags2;
- X#endif
- X /* if soft init mode: don't set port registers if cflag didn't change */
- X if ((init_type == SOFT_INIT) && !((cflag ^ fip->cflag)
- X & (CBAUD | CSIZE | CSTOPB
- X | PARENB | PARODD)))
- X goto setflags;
- X
- X /* lock transmitter and wait until it is empty */
- X fip->device_flags.s |= DF_XMIT_LOCKED;
- X while (fip->device_flags.i & (DF_XMIT_BUSY | DF_XMIT_BREAK
- X | DF_GUARD_TIMEOUT))
- X (void) sleep ((caddr_t) &fip->device_flags.i, PZERO - 1);
- X
- X /* hangup line if it is baud rate 0, else enable line */
- X if ((cflag & CBAUD) == B0)
- X {
- X fip->mcr &= (fip->o_state & OS_WAIT_OPEN)
- X ? ~fip->modem.m.ei
- X : ~fip->modem.m.eo;
- X fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
- X fip->device_flags.s &= ~DF_MODEM_ENABLED;
- X }
- X else
- X {
- X if (!(fip->device_flags.i & DF_MODEM_ENABLED))
- X {
- X fip->mcr |= (fip->o_state & OS_WAIT_OPEN)
- X ? fip->modem.m.ei
- X : fip->modem.m.eo;
- X fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
- X fip->device_flags.s |= DF_MODEM_ENABLED;
- X }
- X }
- X
- X /* don't change break flag */
- X fip->lcr &= LC_SET_BREAK_LEVEL;
- X
- X /* set character size */
- X switch (cflag & CSIZE)
- X {
- X case CS5:
- X fip->lcr |= LC_WORDLEN_5;
- X break;
- X
- X case CS6:
- X fip->lcr |= LC_WORDLEN_6;
- X break;
- X
- X case CS7:
- X fip->lcr |= LC_WORDLEN_7;
- X break;
- X
- X default:
- X fip->lcr |= LC_WORDLEN_8;
- X break;
- X }
- X
- X /* set # of stop bits */
- X if (cflag & CSTOPB)
- X fip->lcr |= LC_STOPBITS_LONG;
- X
- X /* set parity */
- X if (cflag & PARENB)
- X {
- X fip->lcr |= LC_ENABLE_PARITY;
- X
- X if (!(cflag & PARODD))
- X fip->lcr |= LC_EVEN_PARITY;
- X }
- X
- X /* set divisor registers only if baud rate is valid */
- X if ((cflag & CBAUD) != B0)
- X {
- X /* get counter divisor for selected baud rate */
- X divisor = fas_speeds [cflag & CBAUD];
- X /* set LCR and baud rate */
- X fas_first_outb (fip, LINE_CTL_PORT, fip->lcr
- X | LC_ENABLE_DIVISOR);
- X fas_outb (fip, DIVISOR_LSB_PORT, divisor);
- X fas_outb (fip, DIVISOR_MSB_PORT, divisor >> 8);
- X }
- X
- X fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
- X
- Xsetflags:
- X /* check dynamic xmit ring buffer size against boundaries,
- X modify it if necessary and update the fas_info structure
- X */
- X if ((cflag & CBAUD) != B0)
- X {
- X xmit_ring_size = fas_xbuf_size [cflag & CBAUD]
- X - tthiwat [cflag & CBAUD];
- X if (xmit_ring_size < MAX_OUTPUT_FIFO_SIZE * 2)
- X {
- Xsetflags2:
- X xmit_ring_size = MAX_OUTPUT_FIFO_SIZE * 2;
- X }
- X if (xmit_ring_size > XMIT_BUFF_SIZE)
- X xmit_ring_size = XMIT_BUFF_SIZE;
- X fip->xmit_ring_size = xmit_ring_size;
- X }
- X
- X /* setup character time for B0 mode */
- X fas_ctimes [B0] = fas_ctimes [cflag & CBAUD];
- X
- X /* disable modem control signals if required by open mode */
- X if (fip->o_state & OS_CLOCAL)
- X cflag |= CLOCAL;
- X
- X /* Select hardware handshake depending on the minor device
- X number and the CTSFLOW and RTSFLOW flags (if they are
- X available).
- X */
- X fip->flow_flags.s &= ~(FF_HWO_HANDSHAKE
- X | FF_HWI_HANDSHAKE
- X | FF_HDX_HANDSHAKE);
- X if (fip->o_state & (OS_HWO_HANDSHAKE | OS_HWI_HANDSHAKE
- X | OS_HDX_HANDSHAKE))
- X {
- X if (fip->o_state & OS_HWO_HANDSHAKE)
- X fip->flow_flags.s |= FF_HWO_HANDSHAKE;
- X if (fip->o_state & OS_HWI_HANDSHAKE)
- X fip->flow_flags.s |= FF_HWI_HANDSHAKE;
- X if (fip->o_state & OS_HDX_HANDSHAKE)
- X fip->flow_flags.s |= FF_HDX_HANDSHAKE;
- X }
- X else
- X {
- X#if defined (CTSFLOW) /* SYSV 3.2 Xenix compatibility */
- X if ((cflag & (CTSFLOW | CLOCAL)) == CTSFLOW)
- SHAR_EOF
- true || echo 'restore of fasi/fas.c failed'
- fi
- echo 'End of ecu320 part 32'
- echo 'File fasi/fas.c is continued in part 33'
- echo 33 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-