jjm@jjmhome.UUCP (Jim Murray) (05/07/89)
This is a replacement async driver for 386 and 286 based unix systems that adds several features that are not supported by vendors drivers. 1. It supports the 16550 uart chips in full fifo mode. 2. It supports modem sharing for input and output. Microport almost supported this feature but none of the other vendors did. 3. It supports hardware flow control. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README asy.c asy.h asy_conf-c1-2 asy_conf-c1-2h # asy_conf-mux4 asy_conf-mux4h config-c1-2 config-mux4 makefile.v386 # makefile.vat patchlevel.h # Wrapped by jjm@jjmplay on Sat May 6 23:26:26 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(12194 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XWhat is this package: X X This is a replacement async driver for 386 and 286 based unix systems X that adds several features that are not supported by vendors drivers. X 1. It supports the 16550 uart chips in full fifo mode. X 2. It supports modem sharing for input and output. X Microport almost supported this feature but none X of the other vendors did. X 3. It supports hardware flow control. X X X This started out as a replacement driver for my home system jjmhome X to allow me to take advantage of the new 16550 uart chips. As I was X working on it I discovered that the current driver for system V/386 X had a lot of problems with it. I think that I have fixed most of X these and at least made the behavior consistent. Once this driver X got out into beta test people wanted to try it on other systems and X with the help of too many people to mention I determined that this X driver will work on most of the 386 systems, and microport sys V/AT. X This driver is slower than the SYS V/AT when used with the standard X uarts - so I only recommend it for AT machines when when the 16550 X uart is installed. X X------------------------------------------------------------------------ X XA little about what it does: X X This driver supports shared line usage by having two logical X devices sharing one physical line. To those familiar with X Microport this is very similar. For the other readers a X brief description follows. For each line there are two X names. For example for the first line the names are tty00 X (minor device 0) and ttyM00 (minor device 128). The tty00 X is used for cu, kermit, and other programs that want to dial X out. It ignores the modem signals and just goes to it. The X ttyM00 line is strictly for getty. When getty calls open on X ttyM00 the driver hangs the open until the modem asserts DCD X and then lets the open complete. If cu opens tty00 while X getty is waiting for the open to complete the device is X given to cu and the getty open must wait for cu to finish X and then will again wait for DCD. If cu tries to open the X tty00 line while getty has ttyM00 open cu will get an error. X If getty tries to open ttyM00 while cu has tty00 open the X getty open will just hang and wait for cu to close the line X and then wait for DCD. To put it simply you should put up a X getty on ttyM00 with a -t 60 and use tty00 for cu and X uucico. X X The modem devices ttyMxx is the minor device of ttyxx plus X 128. See the makefile for device names. X X------------------------------------------------------------------------ X XA little about what it supports: X X The driver supports and has been tested on many async cards X and mux boards. It supports most combinations of shared X interrupts. The current driver supports 16450, 16550 and X um82450. It is also reported to work on the 8250B. I X suspect that it will not work on some of the earlier 8250 and X 8250A parts, due to various bugs and speed problems in these X early parts. Since these parts have no place in an AT or other X high performance systems I did nothing to try to support them. X X Take a look at the various samples of asy_conf-xxxx for details X of how to set up for various devices. X X------------------------------------------------------------------------ X XWhats in this package: X README This file. X X asy.h The header file for the driver. X X asy.c The driver itself. X X asy_conf-xxxxx These are samples of what asy_conf.h must look X like. You can either copy one of these to X asy_conf.h use it as a template to create your X own asy_conf.h. X X asy_conf-c1-2 For com1 and com2. Equivalent to the standard X driver supplied by uport. X X asy_conf-c1-2h For com1 and com2. Equivalent to the standard X driver supplied by uport but with hardware flow X control turned on. X X asy_conf-mux4 For the MU-440 four line mux board. X X asy_conf-mux4h For the MU-440 four line mux board with X hardware flow control truned on. X X config-xxxxx This is for SYS V/386 only. You should pick the one X that matches your configuration and copy it to config. X X config-c1-2 For com1 and com2. Equivalent to the standard X driver supplied by uport. X X config-mux4 For the MU-440 four line mux board. X X makefile.v386 a makefile for SYS V/386 systems. This is generic X and should work for all configurations of lines X and interrupts. X X makefile.vat a makefile for SYS V/AT systems. I do not have X SYS V/AT so this file was supplied to me by one X of my early beta test sites. It contains specific X configuration information for 2 lines using int X 4 and 3 and devices tty0 tty1 ttyM0 and ttyM0. X This will have to be edited for other combinations X of lines and devices. X X patchlevel.h Just a reference file for future updates. X X------------------------------------------------------------------------ X XWhat you will need to use this package: X X You will need a one of the above mentioned systems with the X link kit and the software development package. X X------------------------------------------------------------------------ X X XRelease History: X X beta.00 Feb 10, 1989 X X Initial beta release. X X ------------------------------------------------------------ X X beta.01 Feb 14, 1989 X X New Features: X Added support for the 16550 uart fifo registers. X X ------------------------------------------------------------ X X beta.02 Feb 22, 1989 X X New Features: X Added support for Microport SYS/V (286 version of unix). X X Bug Fixes: X Fixed bug in asymintr that caused hangup on non modem X lines when any modem interrupt came in. X X ------------------------------------------------------------ X X beta.03 Feb 23, 1989 X X New Features: X X NONE X X Bug Fixes: X X Changed modem interrupt code to not look at the delta X bit on the uart but to actually look at the DCD bit X directly. I believe there is a problem in some of the X older versions of the 8550 chip that forgets to set this X bit sometimes. The 16450 and 16550 chips do not suffer X this problem. X X ------------------------------------------------------------ X X beta.04 Feb 25, 1989 X beta.05 Mar 02, 1989 X X These were two experimental changes of little interest X to most people. Both changes were backed out. These X two versions were not generally released. X X ------------------------------------------------------------ X X beta.06 Fri Mar 10 21:04:23 EST 1989 X X New Features this release. X X First. With the help of the Telebit support people I X have been able to solve the problem with the TB+ not X resetting the port speed when a dialin hangs up. The X problem is actually in the TB+ but fixable in the X driver. The symptoms of the problem are that when a X person calls in at low speed and hangs up the port speed X is not reset to the firmware defaults. Telebit informs X me that this is a bug in the firmware that was X discovered late in the production cycle. The problem is X that the modem only resets on the on to off transition X of dtr and dtr is ignored while the modem is hanging up. X What happens is that carrier is dropped, the modem X starts to hang up and drops dcd. The driver then turns X around and drops dtr. The modem is still in the process X of hanging up at this time and misses the transition. X The fix is to delay 100msec after the dcd interrupt X before dropping dtr. This has fixed the problem. X Telebit also informed me that it was only necessary to X drop dtr for 100msec so I have done that. There are two X new parameters HANGUP_DELAY which is the delay time and X HANGUP_TIME which is the hangup time. I suggest that X you leave the HANGUP_DELAY alone. It sure wont hurt X anything on non TB systems and will solve the problem on X TB systems. You may have to make HANGUP_TIME longer for X older modems. I know of no modems that won't hangup X with 1 second so this should probably be the longest. X X I have invented a new locking scheme get_device_lock and X release_device_lock to cover the hangup time. This was X mostly a code cleanup but it does prevent the hangup X time from getting cut short by another process opening X the device again. X X I rethought the masking issues again and removed some X more of the spltty() calls and made the remaining ones X cover much less code. I am now satisfied that I am X masked about as little as possible. X X Bug Fixes: X X NONE X X ------------------------------------------------------------ X X beta.07 Wed Apr 26, 1989 X X This was a special relase and not of general interest. X X ------------------------------------------------------------ X X beta.08 Sat Apr 29, 1989 X X New Features this release: X X First. I have added support for the DFI MU-440 4 line X mux board. This board is supposed to be a clone of the X AST 4 line mux board. The documentation with this board X was virtually non existent so I had to guess at the use X of the interrupt port. It can be read and it returns a X bitmap representing the uarts that interrupted. I X elected to ignore this for now and just poll the uarts. X The reason I did this is that I do not understand the X hardware well enough to trust the flags. I discovered X that one must write an 0x80 to the interrupt port to X enable interrupts from the card. I discovered that X under some set of conditions this has to be re-enabled X at the end of an interrupt so I just do it every time. X This seems to work. If anyone has further documentation X on how this card (or the AST card) works I would X appreciate hearing from you. X X Second. The driver now supports hardware flow control. X I elected to support this independently from xoff and X xon. The hardware flow control really protects the X buffers in the modem and the buffers in the driver. I X believe that this is the correct approach. I have a bit X for each uart in the configuration that enables hw flow. X X Third. I split out the configuration information into a X separate include file so that I could supply several X different sample configurations with this package. X X X Bug Fixes: X X A bug in shared interrupts that could cause loss of X interrupts in certain conditions has been fixed. X X ------------------------------------------------------------ X X release 1.0 Sat May 6, 1989 X X First general release. X X--------------------------------------------------------------------- X XOutstand issues and crocks. X X The only one at the moment is the lack of better documentation X for configuring the driver. X X-------------------------------------------------------------------- X XGENERAL NOTES: X X Now that the driver seems solid I plan to work on performance X issues. X X--- XJim Murray encore!cloud9!jjmhome!jjm X2 Mohawk Circle harvard!m2c!jjmhome!jjm XWestboro Mass 01581 jjm%jjmhome@m2c.m2c.org XUSA voice (508) 366-2813 END_OF_FILE if test 12194 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'asy.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'asy.c'\" else echo shar: Extracting \"'asy.c'\" \(19299 characters\) sed "s/^X//" >'asy.c' <<'END_OF_FILE' X/* Async driver for 386 and AT versions of system V UNIX */ X X/* Written by XJim Murray encore!cloud9!jjmhome!jjm X2 Mohawk Circle harvard!m2c!jjmhome!jjm XWestboro Mass 01581 jjm%jjmhome@m2c.m2c.org XUSA voice (508) 366-2813 X*/ X X/* RELEASE 1.00 */ X X#if !defined (__GNUC__) && !defined (iAPX286) X#include <sys/inline.h> X#endif X X#include "asy.h" X X#include "asy_conf.h" X X#define NUM_LOGICAL_UNITS (NUM_PHYSICAL_UNITS * 2) X X/* asy_is_initted Flag to indicate that we have been thur 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 */ Xuint asy_is_initted = 0; X X/* the values for the various baud rates */ X Xushort asyspeeds [] = X{ 0, 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/* array of structures to hold all info for a physical minor device */ Xstruct asy_info asy_info[NUM_PHYSICAL_UNITS]; X X/* array of ttys for logical minor devices */ Xstruct tty asy_tty[NUM_LOGICAL_UNITS]; X X/* array of linked lists of asy_info structures for each interrupt vector X this is filled in at init time X */ Xstatic struct asy_info *asy_vector_users[NUM_INT_VECTORS]; X Xextern int ttrstrt (); X Xint asyinit (); Xint asyopen (); Xint asyclose (); Xint asyread (); Xint asywrite (); Xint asyioctl (); Xint asyparam (); Xint asyintr (); Xint asyxintr (); Xint asymintr (); Xint asyproc (); Xstatic void open_device(); Xstatic void close_device(); Xstatic void get_device_lock(); Xstatic void release_device_lock(); X X/* asyinit X This routine checks for the presense of the devices in the asy_port X array and if the device is present tests and initializes it. X During the initialization if the device is determined to be a X NS16550A chip has_fifo is set and the fifo will be used. X*/ X Xint Xasyinit () X{ X register struct asy_info *aip; X uint unit; X uint port; X X if (asy_is_initted) X return; X X asy_is_initted = TRUE; X X for (unit = 0; unit < NUM_PHYSICAL_UNITS; unit++) X { X aip = &asy_info[unit]; X if ((port = asy_port[unit]) != 0) X { X /* init all of its ports */ X aip->rec_data_port = port + RCV_DATA_OFFSET; X aip->xmt_data_port = port + XMT_DATA_OFFSET; X aip->int_ena_port = port + INT_ENABLE_OFFSET; X aip->int_id_port = port + INT_ID_OFFSET; X aip->fifo_ctrl_port = port + FIFO_CTL_OFFSET; X aip->line_ctrl_port = port + LINE_CTL_OFFSET; X aip->mdm_ctrl_port = port + MDM_CTL_OFFSET; X aip->line_stat_port = port + LINE_STATUS_OFFSET; X aip->mdm_stat_port = port + MDM_STATUS_OFFSET; X aip->div_lsb_port = port + DIVISOR_LSB_OFFSET; X aip->div_msb_port = port + DIVISOR_MSB_OFFSET; X aip->recv_ring_put_ptr = aip->recv_buffer; X aip->recv_ring_take_ptr = aip->recv_buffer; X aip->recv_ring_cnt = 0; X aip->hardware_hand_shake = asy_flow[unit]; X X aip->ier = 0; X outb (INT_ENABLE_PORT, aip->ier);/* disable all ints */ X if (inb (INT_ENABLE_PORT) != aip->ier) X continue; /* a hardware error */ X X aip->mcr = asy_mcb[unit] | (INITIAL_MDM_CONTROL); X outb (MDM_CTL_PORT, aip->mcr); X X aip->lcr = INITIAL_LINE_CONTROL; X outb (LINE_CTL_PORT, aip->lcr | LC_ENABLE_DIVISOR); X outb (DIVISOR_LSB_PORT, INITIAL_BAUD_RATE); X outb (DIVISOR_MSB_PORT, (INITIAL_BAUD_RATE) >> 8); X outb (LINE_CTL_PORT, aip->lcr); X X outb (FIFO_CTL_PORT, STANDARD_FIFO_SETUP); X if ((inb (INT_ID_PORT) & II_FIFO_ENABLED) == II_FIFO_ENABLED) X { /* we have here a 16550 type chip */ X aip->has_fifo = TRUE; X } X else X { X aip->has_fifo = FALSE; X } X /* clear and disable the fifo */ X outb (FIFO_CTL_PORT, STANDARD_FIFO_CLEAR); X X /* clear potential interrupts */ X inb (LINE_STATUS_PORT); X inb (MDM_STATUS_PORT); X inb (RCV_DATA_PORT); X inb (INT_ID_PORT); X /* show that it is present and configured */ X aip->device_flags = DF_DEVICE_CONFIGURED; X /* link in as interrupt user */ X aip->next_interrupt_user = asy_vector_users[asy_vec[unit]]; X asy_vector_users[asy_vec[unit]] = aip; X if (asy_mux_port [asy_vec[unit]]) X { X outb (asy_mux_port [asy_vec[unit]], 0x80); X } X } X } X} X X/* Open a line */ X X/* There are a few differneces between this and a normal serial X device. X 1. For each physical minor device there are two logical minor X devices. X X The first device (ttyxx) acts like a normal device with X CLOCAL set. That is is ignores the state of DCD. X X The second device ttyM00 (minor device + 128) waits for X dcd. It will wait for any users of ttyxx to close before X allowing the open to complete. When this device is open X tty00 can not be opened. X*/ X X Xasyopen (dev, flag) Xint dev; Xint flag; X{ X register struct asy_info *aip; X register struct tty *ttyp; X int opening_getty_version; X int physical_unit; X int old_level; X X physical_unit = GET_UNIT (dev); X X if (physical_unit >= NUM_PHYSICAL_UNITS) X { X u.u_error = ENXIO; X return; X } X X aip = &asy_info[physical_unit]; X X if (!(aip->device_flags & DF_DEVICE_CONFIGURED)) X { X u.u_error = ENXIO; X return; X } X X opening_getty_version = DEV_FOR_GETTY (dev); X X while (opening_getty_version && (aip->o_state & OS_OPEN_FOR_DIALOUT)) X { X sleep ((caddr_t) &aip->o_state, TTIPRI); X } X X if (!opening_getty_version && (aip->o_state & OS_OPEN_FOR_GETTY)) X { X u.u_error = EIO; X return; X } X X if (opening_getty_version) X aip->tty = ttyp = &asy_tty[physical_unit + NUM_PHYSICAL_UNITS]; X else X aip->tty = ttyp = &asy_tty[physical_unit]; X X if (!(ttyp->t_state & (ISOPEN | WOPEN))) X { X ttinit (ttyp); X ttyp->t_proc = asyproc; X if (!opening_getty_version) X ttyp->t_cflag |= CLOCAL; X else X ttyp->t_cflag &= ~CLOCAL; X } X X get_device_lock (aip); X if (!(aip->device_flags & DF_DEVICE_OPEN)) X open_device(aip, opening_getty_version); X release_device_lock (aip); X X old_level = spltty(); X X if ((inb (MDM_STATUS_PORT) & MS_DCD_PRESENT) X || (ttyp->t_cflag & CLOCAL) X || !opening_getty_version) X ttyp->t_state |= CARR_ON; X else X ttyp->t_state &= ~CARR_ON; X X if (!(flag & FNDELAY)) X { X while ((ttyp->t_state & CARR_ON) == 0) /* no carrier */ X { X ttyp->t_state |= WOPEN; X if (sleep((caddr_t) &ttyp->t_canq, TTIPRI | PCATCH)) X { X ttyp->t_state &= ~WOPEN; X if (!(aip->o_state & OS_OPEN_FOR_DIALOUT)) X close_device (aip); X longjmp (u.u_qsav, 1); X } X } X } X X (*linesw [ttyp->t_line].l_open) (ttyp); X X if (opening_getty_version) X aip->o_state |= OS_OPEN_FOR_GETTY; X else X aip->o_state |= OS_OPEN_FOR_DIALOUT; X X splx (old_level); X} X X Xasyclose (dev) Xint dev; X{ X register struct asy_info *aip; X register struct tty *ttyp; X int closing_getty_version; X int physical_unit; X int old_level; X X physical_unit = GET_UNIT (dev); X X closing_getty_version = DEV_FOR_GETTY (dev); X X aip = &asy_info[physical_unit]; X X if (closing_getty_version) X ttyp = &asy_tty[physical_unit + NUM_PHYSICAL_UNITS]; X else X ttyp = &asy_tty[physical_unit]; X X (*linesw [ttyp->t_line].l_close) (ttyp); X X old_level = spltty(); X get_device_lock(aip); X X if (closing_getty_version) X { X ttyp->t_state &= ~WOPEN; /* not waiting any more */ X aip->o_state &= ~OS_OPEN_FOR_GETTY; X if (!aip->o_state & OS_OPEN_FOR_DIALOUT) X close_device (aip); X } X else X { X aip->o_state &= ~OS_OPEN_FOR_DIALOUT; X /* get the getty version of the tty structure */ X aip->tty = &asy_tty[physical_unit + NUM_PHYSICAL_UNITS]; X delay (HANGUP_DELAY); X close_device (aip); X delay (HANGUP_TIME); /* guarantee hangup */ X if (aip->tty->t_state & WOPEN) X open_device(aip, TRUE); X wakeup ((caddr_t) &aip->o_state); X } X release_device_lock(aip); X splx (old_level); X return; X} X Xasyread (dev) Xint dev; X{ X register struct asy_info *aip; X register struct tty *ttyp; X X aip = &asy_info [GET_UNIT (dev)]; X X ttyp = aip->tty; X X if ((aip->h_state & HWISTOP) && ttyp->t_rawq.c_cc < TTXOLO) X { X aip->mcr |= MC_SET_RTS; X outb (MDM_CTL_PORT, aip->mcr); X aip->h_state &= ~HWISTOP; X } X X (*linesw [ttyp->t_line].l_read) (ttyp); X} X Xint Xasywrite (dev) Xint dev; X{ X register struct tty *ttyp; X X ttyp = asy_info [GET_UNIT (dev)].tty; X X (*linesw [ttyp->t_line].l_write) (ttyp); X} X Xint Xasyioctl (dev, cmd, arg3, arg4) X int dev; X int cmd; X union ioctl_arg arg3; X int arg4; X{ X register struct asy_info *aip; X X aip = &asy_info [GET_UNIT (dev)]; X X if (ttiocom (aip->tty, cmd, arg3, arg4)) X asyparam (aip); X} X Xint Xasyparam (aip) X register struct asy_info *aip; X{ X register struct tty *ttyp; X short divisor; X int old_level; X X old_level = spltty(); X X ttyp = aip->tty; X X if ((ttyp->t_cflag & CBAUD) == B0) X { X aip->mcr &= ~MC_SET_DTR; X outb (MDM_CTL_PORT, aip->mcr); X splx (old_level); X return; X } X X switch (ttyp->t_cflag & CSIZE) X { X default: X case CS8: X aip->lcr = LC_WORDLEN_8; X break; X X case CS5: X aip->lcr = LC_WORDLEN_5; X break; X X case CS6: X aip->lcr = LC_WORDLEN_6; X break; X X case CS7: X aip->lcr = LC_WORDLEN_7; X break; X } X X if (ttyp->t_cflag & CSTOPB) X aip->lcr |= LC_STOPBITS_LONG; X X if (ttyp->t_cflag & PARENB) X { X aip->lcr |= LC_ENABLE_PARITY; X X if (! (ttyp->t_cflag & PARODD)) X aip->lcr |= LC_EVEN_PARITY; X } X divisor = asyspeeds [ttyp->t_cflag & CBAUD]; X outb (LINE_CTL_PORT, aip->lcr | LC_ENABLE_DIVISOR); X outb (DIVISOR_LSB_PORT, (char) divisor); X outb (DIVISOR_MSB_PORT, (char) (divisor >> 8)); X outb (LINE_CTL_PORT, aip->lcr); X splx (old_level); X} X Xint Xasyintr (vect) X int vect; X{ X register struct asy_info *aip; X int done = FALSE; X X#if defined (iAPX286) X vect -= 32; X#endif X X /* I believe that the 8259 is set up for edge trigger therefore X I must loop until I make a complete pass without getting X any uarts that are interrupting X */ X X while (!done) X { X done = TRUE; X X for (aip = asy_vector_users[vect]; aip != NULL; X aip = aip->next_interrupt_user) X { X /* only ones that we expect ints from */ X while (aip->ier) X { X unchar int_id; X unchar line_status; X X int_id = inb (INT_ID_PORT); X if (int_id & 0x01) X break; X X done = FALSE; /* not done if we got one */ X while ((line_status = inb (LINE_STATUS_PORT)) X & LS_RCV_INT) X { X ushort charac; X X charac = (line_status & LS_RCV_INT) << 8; X X if (line_status & LS_RCV_AVAIL) X charac |= inb (RCV_DATA_PORT); X X if (aip->recv_ring_cnt != RECV_BUFF_SIZE) X { X *aip->recv_ring_put_ptr++ = charac; X aip->recv_ring_cnt++; X if (aip->recv_ring_put_ptr X == &aip->recv_buffer[RECV_BUFF_SIZE]) X aip->recv_ring_put_ptr X = &aip->recv_buffer[0]; X } X else X aip->overruns++; X } X if ((line_status & LS_XMIT_AVAIL) X && (aip->tty->t_state & BUSY)) X asyxintr(aip); X if ((int_id & 7) == II_MODEM_STATE) X asymintr (aip); X } X if (aip->recv_ring_cnt) X { X asyrproc(aip); X if ((aip->hardware_hand_shake) X && (aip->tty->t_rawq.c_cc > TTXOHI) X && (!(aip->h_state & HWISTOP)) ) X { X aip->h_state |= HWISTOP; X aip->mcr &= ~MC_SET_RTS; X outb (MDM_CTL_PORT, aip->mcr); X } X sysinfo.rcvint++; X } X } X } X /* clear the mux interrupt since we are about to scan all X of the ports that share this interrupt vector X */ X X if (asy_mux_port [vect]) X { X outb (asy_mux_port [vect], 0x80); X } X} X Xint Xasyxintr (aip) X register struct asy_info *aip; X{ X X register struct tty *ttyp; X X ttyp = aip->tty; X sysinfo.xmtint++; X X if (aip->h_state & HWOSTOP) X { X ttyp->t_state &= ~(BUSY); X } X else if (ttyp->t_state & TTXON) X { X#if STATISTICS X aip->tra_buckets[0]++; X#endif X outb (XMT_DATA_PORT, CSTART); X ttyp->t_state &= ~TTXON; X } X else if (ttyp->t_state & TTXOFF) X { X#if STATISTICS X aip->tra_buckets[0]++; X#endif X outb (XMT_DATA_PORT, CSTOP); X ttyp->t_state &= ~TTXOFF; X } X else X { X ttyp->t_state &= ~(BUSY); X asyproc (ttyp, T_OUTPUT); X } X} X Xint Xasymintr (aip) X register struct asy_info *aip; X{ X register struct tty *ttyp; X unchar mdm_state; X X ttyp = aip->tty; X X sysinfo.mdmint++; X X mdm_state = inb (MDM_STATUS_PORT); X X#if 0 X printf ("MDM %x\n", mdm_state); X#endif X X if (aip->hardware_hand_shake) X { X if (mdm_state & MS_CTS_PRESENT) X { X if (aip->h_state & HWOSTOP) X { X aip->h_state &= ~HWOSTOP; X asyproc (ttyp, T_OUTPUT); X } X } X else X { X if (! (aip->h_state & HWOSTOP)) X { X aip->h_state |= HWOSTOP; X } X } X } X X if ((ttyp->t_cflag & CLOCAL) || (aip->o_state & OS_OPEN_FOR_DIALOUT)) X return; X X if (mdm_state & MS_DCD_PRESENT) X { X ttyp->t_state |= CARR_ON; X wakeup (&ttyp->t_canq); X } X else X { X if (ttyp->t_state & CARR_ON) X { X if (ttyp->t_state & ISOPEN) X { X signal (ttyp->t_pgrp, SIGHUP); X ttyflush (ttyp, FREAD | FWRITE); X } X ttyp->t_state &= ~ CARR_ON; X } X } X} X Xasyrproc(aip) X register struct asy_info *aip; X{ X register struct tty *ttyp; X static char metta[4]; X int csize = 0; X X ttyp = aip->tty; X X if (ttyp->t_state & ISOPEN) X { X#if STATISTICS X if (aip->recv_ring_cnt <= 16) X aip->rec_buckets[aip->recv_ring_cnt]++; X else X aip->rec_buckets[0]++; X#endif X X while (aip->recv_ring_cnt) X { X ushort value; X unchar status; X unchar rchar; X unchar ichar; X X value = *aip->recv_ring_take_ptr++; X if (aip->recv_ring_take_ptr X == &aip->recv_buffer[RECV_BUFF_SIZE]) X aip->recv_ring_take_ptr = &aip->recv_buffer[0]; X X aip->recv_ring_cnt--; X X ichar = rchar = (value & 0xFF); X status = (value >> 8); X X if (ttyp->t_iflag & ISTRIP) X ichar &= 0x7F; X X if ((status & LS_PARITY_ERROR) X && !(ttyp->t_iflag & INPCK)) X status &= ~LS_PARITY_ERROR; X X if (status & (LS_ANY_ERROR | LS_BREAK_DETECTED)) X { X /* maybe this should be X if (status & LS_RCV_AVAIL) X */ X if (rchar X && (ttyp->t_iflag & PARMRK) X && !(ttyp->t_iflag & IGNPAR)) X { X metta[csize++] = rchar; X metta[csize++] = 0; X metta[csize++] = 0xff; X } X else if (!(ttyp->t_iflag & IGNBRK)) X { X if (ttyp->t_iflag & BRKINT) X (*linesw [ttyp->t_line].l_input) X (ttyp, L_BREAK); X else if (ttyp->t_iflag & PARMRK) X { X metta[csize++] = rchar; X metta[csize++] = 0; X metta[csize++] = 0xff; X } X else X metta [csize++] = ichar; X } X } X else X { X if (ttyp->t_iflag & IXON) X { X if (ttyp->t_state & TTSTOP) X { X if ((ichar == CSTART) X || (ttyp->t_iflag & IXANY)) X asyproc (ttyp, T_RESUME); X } X else X { X if (ichar == CSTOP) X asyproc (ttyp, T_SUSPEND); X } X if ((ichar == CSTART) X || (ichar == CSTOP)) X continue; X } X X if ((ichar == 0xff) && (ttyp->t_iflag & PARMRK)) X metta [csize++] = ichar; X X metta [csize++] = ichar; X X } X X if (ttyp->t_rbuf.c_ptr == NULL) X continue; X X while (csize) X { X *ttyp->t_rbuf.c_ptr++ = metta [--csize]; X ttyp->t_rbuf.c_count--; X if (ttyp->t_rbuf.c_count == 0) X { X ttyp->t_rbuf.c_ptr -= ttyp->t_rbuf.c_size; X (*linesw [ttyp->t_line].l_input) (ttyp, L_BUF); X if (ttyp->t_rbuf.c_ptr == NULL) X break; X } X } X } X if (ttyp->t_rbuf.c_ptr != NULL) X { X ttyp->t_rbuf.c_ptr -= ttyp->t_rbuf.c_size X - ttyp->t_rbuf.c_count; X (*linesw [ttyp->t_line].l_input) (ttyp, L_BUF); X } X } X else X { X aip->recv_ring_take_ptr = aip->recv_ring_put_ptr; X aip->recv_ring_cnt = 0; X } X} X Xint Xasyproc (ttyp, arg2) X register struct tty *ttyp; X X int arg2; X{ X register struct asy_info *aip; X int old_level; X int num_to_output; X int physical_unit; X X physical_unit = ttyp - &asy_tty[0]; X if (physical_unit >= NUM_PHYSICAL_UNITS) X physical_unit -=NUM_PHYSICAL_UNITS; X X aip = &asy_info[physical_unit]; X X old_level = spltty(); X X switch (arg2) X { X case T_TIME: X ttyp->t_state &= ~ TIMEOUT; X aip->lcr &= ~LC_SET_BREAK_LEVEL; X outb (LINE_CTL_PORT, aip->lcr); X goto start; X X case T_WFLUSH: X ttyp->t_tbuf.c_size -= ttyp->t_tbuf.c_count; X ttyp->t_tbuf.c_count = 0; X X case T_RESUME: X ttyp->t_state &= ~ TTSTOP; X X case T_OUTPUT: Xstart: X if (ttyp->t_state & (TTSTOP | BUSY | TIMEOUT) X || (aip->h_state & HWOSTOP)) X break; X X if (ttyp->t_state & TTXON) X { X#if STATISTICS X aip->tra_buckets[0]++; X#endif X outb (XMT_DATA_PORT, CSTART); X ttyp->t_state &= ~TTXON; X ttyp->t_state |= (BUSY); X break; X } X X if (ttyp->t_state & TTXOFF) X { X#if STATISTICS X aip->tra_buckets[0]++; X#endif X outb (XMT_DATA_PORT, CSTOP); X ttyp->t_state &= ~TTXOFF; X ttyp->t_state |= (BUSY); X break; X } X X /* check if tbuf is empty */ X if ((ttyp->t_tbuf.c_ptr == NULL) || (ttyp->t_tbuf.c_count == 0)) X { X if (ttyp->t_tbuf.c_ptr != NULL) X ttyp->t_tbuf.c_ptr -= ttyp->t_tbuf.c_size; X if (! ((*linesw [ttyp->t_line].l_output) (ttyp) & CPRES)) X break; X } X X if (aip->has_fifo) /* 16550 chip ? */ X num_to_output = min (ttyp->t_tbuf.c_count, X OUTPUT_FIFO_SIZE); X else X num_to_output = 1; X X ttyp->t_state |= (BUSY); X#if STATISTICS X aip->tra_buckets[num_to_output]++; X#endif X while (num_to_output--) X { X outb (XMT_DATA_PORT, *ttyp->t_tbuf.c_ptr++); X ttyp->t_tbuf.c_count--; X } X break; X X case T_SUSPEND: X ttyp->t_state |= TTSTOP; X break; X X case T_BLOCK: X ttyp->t_state &= ~TTXON; X ttyp->t_state |= TBLOCK; X ttyp->t_state |= TTXOFF; X goto start; X X case T_RFLUSH: X if (! (ttyp->t_state & TBLOCK)) X break; X X case T_UNBLOCK: X ttyp->t_state &= ~ (TTXOFF | TBLOCK); X ttyp->t_state |= TTXON; X goto start; X X case T_BREAK: X aip->lcr |= LC_SET_BREAK_LEVEL; X outb (LINE_CTL_PORT, aip->lcr); X ttyp->t_state |= TIMEOUT; X timeout (ttrstrt, ttyp, HZ / 4); /* 250 msec */ X break; X X case T_SWTCH: X break; X X case T_PARM: X asyparam (aip); X break; X } X splx(old_level); X} X Xstatic void Xget_device_lock(aip) X register struct asy_info *aip; X{ X while (aip->device_flags & DF_DEVICE_LOCKED) X { X sleep((caddr_t) &aip->device_flags, PZERO -1); X } X aip->device_flags |= DF_DEVICE_LOCKED; X} X Xstatic void Xrelease_device_lock(aip) X register struct asy_info *aip; X{ X aip->device_flags &= ~DF_DEVICE_LOCKED; X wakeup (&aip->device_flags); X} X Xvoid Xopen_device(aip, opening_getty_version) X register struct asy_info *aip; X int opening_getty_version; X{ X if (aip->has_fifo) X { X outb (FIFO_CTL_PORT, STANDARD_FIFO_CLEAR); X outb (FIFO_CTL_PORT, STANDARD_FIFO_SETUP); X } X asyparam (aip); X X aip->mcr |= (MC_SET_DTR | MC_SET_RTS); X outb (MDM_CTL_PORT, aip->mcr); X X if (opening_getty_version) X aip->ier |= IE_GETTY_MODE; X else X aip->ier = IE_DIALOUT_MODE; X X outb (INT_ENABLE_PORT, aip->ier); X X aip->device_flags |= DF_DEVICE_OPEN; X} X Xvoid Xclose_device(aip) X register struct asy_info *aip; X{ X aip->device_flags &= ~DF_DEVICE_OPEN; X aip->ier = 0; /* disable all ints from uart */ X aip->mcr &= ~(MC_SET_DTR | MC_SET_RTS); X outb (INT_ENABLE_PORT, aip->ier); X outb (MDM_CTL_PORT, aip->mcr); X if (aip->has_fifo) X { X outb (FIFO_CTL_PORT, STANDARD_FIFO_CLEAR); X } X return; X} X X#if defined (NEED_PUT_GETCHAR) X Xint Xasyputchar(arg1) X unchar arg1; X{ X register struct asy_info *aip; X X if (!asy_is_initted) X asyinit(); X X aip = &asy_info [0]; X if (aip->device_flags & DF_DEVICE_CONFIGURED) X { X while (!(inb (LINE_STATUS_PORT) & LS_XMIT_AVAIL)) X ; X outb (XMT_DATA_PORT, arg1); X if (arg1 == 10) X asyputchar(13); X } X} X Xint Xasygetchar() X{ X register struct asy_info *aip; X X if (!asy_is_initted) X asyinit(); X X aip = &asy_info[0]; X if ((aip->device_flags & DF_DEVICE_CONFIGURED) X && (inb (LINE_STATUS_PORT) & LS_RCV_AVAIL)) X { X return (inb (RCV_DATA_PORT)); X } X else X { X return (-1); X } X} X#endif END_OF_FILE if test 19299 -ne `wc -c <'asy.c'`; then echo shar: \"'asy.c'\" unpacked with wrong size! fi # end of 'asy.c' fi if test -f 'asy.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'asy.h'\" else echo shar: Extracting \"'asy.h'\" \(7107 characters\) sed "s/^X//" >'asy.h' <<'END_OF_FILE' X/* asy.h */ X X#include <sys/param.h> X#include <sys/types.h> X#include <sys/signal.h> X#include <sys/buf.h> X#include <sys/iobuf.h> X#include <sys/dir.h> 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#include <sys/termio.h> X#include <sys/ioctl.h> X X#if defined (iAPX286) Xtypedef unsigned char unchar; /* V/AT does not define unchar in types */ X#define spltty spl7 /* V/AT does not have spltty */ X#endif X X/* STATISTICS says collect interrupt counts */ X#define STATISTICS 1 X X#ifdef NDEBUG X#define myassert(EX) X#else Xextern void printf(); X#define myassert(EX) if (EX) ; else printf("assert %s file = %s line = %d\n","EX", __FILE__, __LINE__) X#endif X X#define RESET 0 X#define SET 1 X X#if !defined (TRUE) X#define TRUE (1) X#endif X#if !defined (FALSE) X#define FALSE (0) X#endif X X/* The following two defines may have to be changed to fit your X local convention for device nodes. They are defined here for X uport makeing the getty device minor device + 128 X*/ X#define GET_UNIT(dev) ((dev) & 0x1f) X#define DEV_FOR_GETTY(dev) (((dev) & 0x80) != 0) X X/* initial line control register. Value will only be meaningfull for X asyputchar and asygetchar and they are only meaningufll if X NEED_PUT_GETCHAR is defined X*/ X#define INITIAL_LINE_CONTROL LC_WORDLEN_8 X X/* initial baud rate. Value will only be meaningfull for X asyputchar and asygetchar and they are only meaningufll if X NEED_PUT_GETCHAR is defined X*/ X#define INITIAL_BAUD_RATE (BAUD_BASE/9600) X X/* initial modem control register. This should probably not have to X be touched. It is here because some terminals used as the console X require one or more of the modem signals set. Again this is realy X only meaningfull for asyputchar and asygetchar and then are only X meaningufll if NEED_PUT_GETCHAR is defined. X*/ X#define INITIAL_MDM_CONTROL 0 X X/* Uncomment the following line if you need asyputchar and asygetchar. X bell tech needs these. Uport has them burried in the kd device. X*/ X X/* #define NEED_PUT_GETCHAR 1 */ X X/****************************************************/ X/* Nothing past this line should have to be changed */ X/****************************************************/ X X#define NUM_INT_VECTORS 16 /* sixteen vectors possible but only X the first eight are normally used X */ X X/* define the states */ X#define HWOSTOP 0x01 X#define HWISTOP 0x02 X X/* define the device status flags */ X X#define DF_DEVICE_CONFIGURED 0x01 /* device is not configured */ X#define DF_DEVICE_OPEN 0x02 /* physical device is open */ X#define DF_DEVICE_LOCKED 0x04 /* physical device locked */ X X/* Description of the NS16550 Asychronous Communications Element */ X X#define RCV_DATA_OFFSET 0 X#define XMT_DATA_OFFSET 0 X#define INT_ENABLE_OFFSET 1 X#define INT_ID_OFFSET 2 X#define FIFO_CTL_OFFSET 2 X#define LINE_CTL_OFFSET 3 X#define MDM_CTL_OFFSET 4 X#define LINE_STATUS_OFFSET 5 X#define MDM_STATUS_OFFSET 6 X#define DIVISOR_LSB_OFFSET 0 X#define DIVISOR_MSB_OFFSET 1 X X/* Define an easy way to refenence the absolute port addresses */ X X#define RCV_DATA_PORT (aip->rec_data_port) X#define XMT_DATA_PORT (aip->xmt_data_port) X#define INT_ENABLE_PORT (aip->int_ena_port) X#define INT_ID_PORT (aip->int_id_port) X#define FIFO_CTL_PORT (aip->fifo_ctrl_port) X#define LINE_CTL_PORT (aip->line_ctrl_port) X#define MDM_CTL_PORT (aip->mdm_ctrl_port) X#define LINE_STATUS_PORT (aip->line_stat_port) X#define MDM_STATUS_PORT (aip->mdm_stat_port) X#define DIVISOR_LSB_PORT (aip->div_lsb_port) X#define DIVISOR_MSB_PORT (aip->div_msb_port) X X/* Miscellaneous Constants: */ X X#define BAUD_BASE (1843200/16) /* 115200 bps */ X#define HANGUP_DELAY ((HZ) / 10) /* 100 msec */ X#define HANGUP_TIME ((HZ) / 10) /* 100 msec */ X X/* Modem Status Port */ X X#define MS_CTS_CHANGED 0x01 X#define MS_DSR_CHANGED 0x02 X#define MS_RING_CHANGED 0x04 X#define MS_DCD_CHANGED 0x08 X#define MS_CTS_PRESENT 0x10 X#define MS_DSR_PRESENT 0x20 X#define MS_RING_PRESENT 0x40 X#define MS_DCD_PRESENT 0x80 X X#define MS_ANY_CHANGE (MS_CTS_CHANGED | MS_DSR_CHANGED | MS_RING_CHANGED | MS_DCD_CHANGED) X X/* interrupt enable port */ X#define IE_RECV_DATA_AVAILABLE 0x01 X#define IE_XMIT_HOLDING_BUFFER_EMPTY 0x02 X#define IE_LINE_STATUS 0x04 X#define IE_MODEM_STATUS 0x08 X X#define IE_DIALOUT_MODE 0x07 X#define IE_GETTY_MODE 0x0F X X/* Interrupt Id Port: */ X X#define II_MODEM_STATE 0x00 X#define II_XMTD_CHAR 0x02 X#define II_RCVD_CHAR 0x04 X#define II_RCV_ERROR 0x06 X#define II_FIFO_TIMEOUT 0x08 X#define II_FIFO_ENABLED 0xC0 X X/* Line Control Port: */ X X#define LC_WORDLEN_MASK 0x03 X#define LC_WORDLEN_5 0x00 X#define LC_WORDLEN_6 0x01 X#define LC_WORDLEN_7 0x02 X#define LC_WORDLEN_8 0x03 X#define LC_STOPBITS_LONG 0x04 X#define LC_ENABLE_PARITY 0x08 X#define LC_EVEN_PARITY 0x10 X#define LC_STICK_PARITY 0x20 X#define LC_SET_BREAK_LEVEL 0x40 X#define LC_ENABLE_DIVISOR 0x80 X X/* Modem Control Port: */ X X#define MC_SET_DTR 0x01 X#define MC_SET_RTS 0x02 X#define MC_SET_OUT1 0x04 X#define MC_SET_OUT2 0x08 /* tristates int line when false */ X#define MC_SET_LOOPBACK 0x10 X X/* Line Status Port: */ X X#define LS_RCV_AVAIL 0x01 X#define LS_OVERRUN 0x02 X#define LS_PARITY_ERROR 0x04 X#define LS_FRAMING_ERROR 0x08 X#define LS_BREAK_DETECTED 0x10 X#define LS_XMIT_AVAIL 0x20 X#define LS_XMIT_COMPLETE 0x40 X X#define LS_ANY_ERROR (LS_OVERRUN | LS_PARITY_ERROR | LS_FRAMING_ERROR) X#define LS_RCV_INT (LS_ANY_ERROR | LS_RCV_AVAIL | LS_BREAK_DETECTED) X X#define RECV_BUFF_SIZE 128 X X/* X this structure contains everything one would like to know about X an open device. There is one of these for each minor device. X*/ X Xstruct asy_info X{ X struct tty *tty; /* the tty structure */ X struct asy_info *next_interrupt_user; X unchar mcr; /* the modem control value */ X unchar lcr; /* the line_control_register value */ X unchar ier; /* interrupt enable register value */ X ushort o_state; /* current open state */ X unchar device_flags; /* flags about the device */ X ushort rec_data_port; /* receive data port */ X ushort xmt_data_port; /* transmit data port */ X ushort int_ena_port; /* interrupt mask port */ X ushort int_id_port; /* interrupt identification port */ X ushort fifo_ctrl_port; /* fifo control port (16550 only) */ X ushort line_ctrl_port; X ushort mdm_ctrl_port; X ushort line_stat_port; X ushort mdm_stat_port; X ushort div_lsb_port; X ushort div_msb_port; X unchar has_fifo; X unchar hardware_hand_shake; X int overruns; X int sperious_interrupt; X int h_state; X int xmit_active; X uint rec_buckets[17]; X uint tra_buckets[17]; X ushort *recv_ring_put_ptr; X ushort *recv_ring_take_ptr; X short recv_ring_cnt; X ushort recv_buffer[RECV_BUFF_SIZE]; X}; X X#define FIFO_ENABLE 0x01 X#define FIFO_CLR_RECV 0x02 X#define FIFO_CLR_XMIT 0x04 X#define FIFO_START_DMA 0x08 X#define FIFO_SIZE_1 0x00 X#define FIFO_SIZE_4 0x40 X#define FIFO_SIZE_8 0x80 X#define FIFO_SIZE_14 0xC0 X#define FIFO_SIZE_MASK 0xC0 X X#define OUTPUT_FIFO_SIZE 16 X X#define STANDARD_FIFO_CLEAR (FIFO_CLR_RECV | FIFO_CLR_XMIT) X#define STANDARD_FIFO_SETUP (FIFO_SIZE_14 | FIFO_ENABLE) X X/* define the local open flags */ X#define OS_OPEN_FOR_DIALOUT 0x01 X#define OS_OPEN_FOR_GETTY 0x02 END_OF_FILE if test 7107 -ne `wc -c <'asy.h'`; then echo shar: \"'asy.h'\" unpacked with wrong size! fi # end of 'asy.h' fi if test -f 'asy_conf-c1-2' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'asy_conf-c1-2'\" else echo shar: Extracting \"'asy_conf-c1-2'\" \(2131 characters\) sed "s/^X//" >'asy_conf-c1-2' <<'END_OF_FILE' X X/* Async device configureation file for 386 and AT versions of system V UNIX */ X X/* This version is for the standard com1 and com2 ports. X */ X X/* Written by XJim Murray encore!cloud9!jjmhome!jjm X2 Mohawk Circle harvard!m2c!jjmhome!jjm XWestboro Mass 01581 jjm%jjmhome@m2c.m2c.org XUSA voice (508) 366-2813 X*/ X X/* This is the number of devices to be handled by this driver X if this number is changed the arrays in asy.c must be filled X in with the base port number and the interrupt vector X*/ X#define NUM_PHYSICAL_UNITS 2 X X/* array of base port addresses */ Xushort asy_port [NUM_PHYSICAL_UNITS] = X{ X 0x3f8, 0x2f8 X}; X X/* array of interrupt vectors */ Xunchar asy_vec [NUM_PHYSICAL_UNITS] = X{ X 0x4, 0x3 X}; X X/* modem control port info. This value is ored into the modem control X value for each uart. This is normaly used to force out2 which is X used to enable the interrupts form the standard com1 and com2 ports. X Several brands of cards have modes that allow them to work in compatable X mode like com1 and com2 or as a mux. One of these cards is the MU-440 X card by DFI. When this card is used with the common interrupt out2 X must not be set or there will be a fight on the buss. X */ X Xunchar asy_mcb [NUM_PHYSICAL_UNITS] = X{ X MC_SET_OUT2, MC_SET_OUT2 X}; X X/* array of hardware flow control flags X A non zero value indicates the the driver should use hardware X handshake on this line. X */ Xunchar asy_flow [NUM_PHYSICAL_UNITS] = X{ X 0x0, 0x0 X}; X X/* array of mux port addresses X Indexed by vector number a non zero value is a port address that X must be read from to get the interrupt vector. X The input value actually contains bits representing the uart that X interrupted but I can find no good documentation on these so I X have elected to poll the uarts. X This port also must be written to enable the interrupts. This X acts similar to the out2 in the standard asy card. X If you are not sure what to do here you should probably not set X any of these X */ X Xushort asy_mux_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}; END_OF_FILE if test 2131 -ne `wc -c <'asy_conf-c1-2'`; then echo shar: \"'asy_conf-c1-2'\" unpacked with wrong size! fi # end of 'asy_conf-c1-2' fi if test -f 'asy_conf-c1-2h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'asy_conf-c1-2h'\" else echo shar: Extracting \"'asy_conf-c1-2h'\" \(2131 characters\) sed "s/^X//" >'asy_conf-c1-2h' <<'END_OF_FILE' X X/* Async device configureation file for 386 and AT versions of system V UNIX */ X X/* This version is for the standard com1 and com2 ports. X */ X X/* Written by XJim Murray encore!cloud9!jjmhome!jjm X2 Mohawk Circle harvard!m2c!jjmhome!jjm XWestboro Mass 01581 jjm%jjmhome@m2c.m2c.org XUSA voice (508) 366-2813 X*/ X X/* This is the number of devices to be handled by this driver X if this number is changed the arrays in asy.c must be filled X in with the base port number and the interrupt vector X*/ X#define NUM_PHYSICAL_UNITS 2 X X/* array of base port addresses */ Xushort asy_port [NUM_PHYSICAL_UNITS] = X{ X 0x3f8, 0x2f8 X}; X X/* array of interrupt vectors */ Xunchar asy_vec [NUM_PHYSICAL_UNITS] = X{ X 0x4, 0x3 X}; X X/* modem control port info. This value is ored into the modem control X value for each uart. This is normaly used to force out2 which is X used to enable the interrupts form the standard com1 and com2 ports. X Several brands of cards have modes that allow them to work in compatable X mode like com1 and com2 or as a mux. One of these cards is the MU-440 X card by DFI. When this card is used with the common interrupt out2 X must not be set or there will be a fight on the buss. X */ X Xunchar asy_mcb [NUM_PHYSICAL_UNITS] = X{ X MC_SET_OUT2, MC_SET_OUT2 X}; X X/* array of hardware flow control flags X A non zero value indicates the the driver should use hardware X handshake on this line. X */ Xunchar asy_flow [NUM_PHYSICAL_UNITS] = X{ X 0x1, 0x1 X}; X X/* array of mux port addresses X Indexed by vector number a non zero value is a port address that X must be read from to get the interrupt vector. X The input value actually contains bits representing the uart that X interrupted but I can find no good documentation on these so I X have elected to poll the uarts. X This port also must be written to enable the interrupts. This X acts similar to the out2 in the standard asy card. X If you are not sure what to do here you should probably not set X any of these X */ X Xushort asy_mux_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}; END_OF_FILE if test 2131 -ne `wc -c <'asy_conf-c1-2h'`; then echo shar: \"'asy_conf-c1-2h'\" unpacked with wrong size! fi # end of 'asy_conf-c1-2h' fi if test -f 'asy_conf-mux4' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'asy_conf-mux4'\" else echo shar: Extracting \"'asy_conf-mux4'\" \(2233 characters\) sed "s/^X//" >'asy_conf-mux4' <<'END_OF_FILE' X X/* Async device configureation file for 386 and AT versions of system V UNIX */ X X/* This version is for the DFI MU440 mux board in expanded mode. This board X is reported to be compatable with the AST 4-port card. X */ X X/* Written by XJim Murray encore!cloud9!jjmhome!jjm X2 Mohawk Circle harvard!m2c!jjmhome!jjm XWestboro Mass 01581 jjm%jjmhome@m2c.m2c.org XUSA voice (508) 366-2813 X*/ X X/* This is the number of devices to be handled by this driver X if this number is changed the arrays in asy.c must be filled X in with the base port number and the interrupt vector X*/ X#define NUM_PHYSICAL_UNITS 4 X X/* array of base port addresses */ Xushort asy_port [NUM_PHYSICAL_UNITS] = X{ X 0x2a0, 0x2a8, 0x2b0, 0x2b8 X}; X X/* array of interrupt vectors */ Xunchar asy_vec [NUM_PHYSICAL_UNITS] = X{ X 0x4, 0x4, 0x4, 0x4 X}; X X/* modem control port info. This value is ored into the modem control X value for each uart. This is normaly used to force out2 which is X used to enable the interrupts form the standard com1 and com2 ports. X Several brands of cards have modes that allow them to work in compatable X mode like com1 and com2 or as a mux. One of these cards is the MU-440 X card by DFI. When this card is used with the common interrupt out2 X must not be set or there will be a fight on the buss. X */ X Xunchar asy_mcb [NUM_PHYSICAL_UNITS] = X{ X 0, 0, 0, 0 X}; X X/* array of hardware flow control flags X A non zero value indicates the the driver should use hardware X handshake on this line. X */ Xunchar asy_flow [NUM_PHYSICAL_UNITS] = X{ X 0x0, 0x0, 0x0, 0x0 X}; X X/* array of mux port addresses X Indexed by vector number a non zero value is a port address that X must be read from to get the interrupt vector. X The input value actually contains bits representing the uart that X interrupted but I can find no good documentation on these so I X have elected to poll the uarts. X This port also must be written to enable the interrupts. This X acts similar to the out2 in the standard asy card. X If you are not sure what to do here you should probably not set X any of these X */ X Xushort asy_mux_port [NUM_INT_VECTORS] = X{ X 0, 0, 0, 0, X 0x2bf, 0, 0, 0, X 0, 0, 0, 0, X 0, 0, 0, 0 X}; END_OF_FILE if test 2233 -ne `wc -c <'asy_conf-mux4'`; then echo shar: \"'asy_conf-mux4'\" unpacked with wrong size! fi # end of 'asy_conf-mux4' fi if test -f 'asy_conf-mux4h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'asy_conf-mux4h'\" else echo shar: Extracting \"'asy_conf-mux4h'\" \(2233 characters\) sed "s/^X//" >'asy_conf-mux4h' <<'END_OF_FILE' X X/* Async device configureation file for 386 and AT versions of system V UNIX */ X X/* This version is for the DFI MU440 mux board in expanded mode. This board X is reported to be compatable with the AST 4-port card. X */ X X/* Written by XJim Murray encore!cloud9!jjmhome!jjm X2 Mohawk Circle harvard!m2c!jjmhome!jjm XWestboro Mass 01581 jjm%jjmhome@m2c.m2c.org XUSA voice (508) 366-2813 X*/ X X/* This is the number of devices to be handled by this driver X if this number is changed the arrays in asy.c must be filled X in with the base port number and the interrupt vector X*/ X#define NUM_PHYSICAL_UNITS 4 X X/* array of base port addresses */ Xushort asy_port [NUM_PHYSICAL_UNITS] = X{ X 0x2a0, 0x2a8, 0x2b0, 0x2b8 X}; X X/* array of interrupt vectors */ Xunchar asy_vec [NUM_PHYSICAL_UNITS] = X{ X 0x4, 0x4, 0x4, 0x4 X}; X X/* modem control port info. This value is ored into the modem control X value for each uart. This is normaly used to force out2 which is X used to enable the interrupts form the standard com1 and com2 ports. X Several brands of cards have modes that allow them to work in compatable X mode like com1 and com2 or as a mux. One of these cards is the MU-440 X card by DFI. When this card is used with the common interrupt out2 X must not be set or there will be a fight on the buss. X */ X Xunchar asy_mcb [NUM_PHYSICAL_UNITS] = X{ X 0, 0, 0, 0 X}; X X/* array of hardware flow control flags X A non zero value indicates the the driver should use hardware X handshake on this line. X */ Xunchar asy_flow [NUM_PHYSICAL_UNITS] = X{ X 0x1, 0x1, 0x1, 0x1 X}; X X/* array of mux port addresses X Indexed by vector number a non zero value is a port address that X must be read from to get the interrupt vector. X The input value actually contains bits representing the uart that X interrupted but I can find no good documentation on these so I X have elected to poll the uarts. X This port also must be written to enable the interrupts. This X acts similar to the out2 in the standard asy card. X If you are not sure what to do here you should probably not set X any of these X */ X Xushort asy_mux_port [NUM_INT_VECTORS] = X{ X 0, 0, 0, 0, X 0x2bf, 0, 0, 0, X 0, 0, 0, 0, X 0, 0, 0, 0 X}; END_OF_FILE if test 2233 -ne `wc -c <'asy_conf-mux4h'`; then echo shar: \"'asy_conf-mux4h'\" unpacked with wrong size! fi # end of 'asy_conf-mux4h' fi if test -f 'config-c1-2' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'config-c1-2'\" else echo shar: Extracting \"'config-c1-2'\" \(253 characters\) sed "s/^X//" >'config-c1-2' <<'END_OF_FILE' X* its character device number 3 Xcharacter(3) X X* its name Xprefix = asy X X* The interrupt vectors handled by this controller Xintvec = 4,3 X X* its mask level Xintpri = SPLTTY X X* the functions it supports Xfunctions = init, open, close, read, write, ioctl, tty END_OF_FILE if test 253 -ne `wc -c <'config-c1-2'`; then echo shar: \"'config-c1-2'\" unpacked with wrong size! fi # end of 'config-c1-2' fi if test -f 'config-mux4' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'config-mux4'\" else echo shar: Extracting \"'config-mux4'\" \(251 characters\) sed "s/^X//" >'config-mux4' <<'END_OF_FILE' X* its character device number 3 Xcharacter(3) X X* its name Xprefix = asy X X* The interrupt vectors handled by this controller Xintvec = 4 X X* its mask level Xintpri = SPLTTY X X* the functions it supports Xfunctions = init, open, close, read, write, ioctl, tty END_OF_FILE if test 251 -ne `wc -c <'config-mux4'`; then echo shar: \"'config-mux4'\" unpacked with wrong size! fi # end of 'config-mux4' fi if test -f 'makefile.v386' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile.v386'\" else echo shar: Extracting \"'makefile.v386'\" \(512 characters\) sed "s/^X//" >'makefile.v386' <<'END_OF_FILE' XINCLSYS=/usr/include/sys XINSDIR=/etc/atconf X XCFLAGS = -O -DINKERNEL X XOBJS = asy.o X Xasy.o: asy.c \ X asy.h \ X asy_conf.h X Xasy_conf.h: X @echo "You must link asy_conf.h to the proper asy_conf-xxxxx file" X @false X Xinstall: asy.o config X cp asy.o $(INSDIR)/modules/asy/asy.o X chmod 644 $(INSDIR)/modules/asy/asy.o X cp config $(INSDIR)/modules/asy/config X chmod 644 $(INSDIR)/modules/asy/config X Xconfig: X @echo "You must link config to the proper config-xxxxx file" X @false X X Xclean: X rm -f asy.o X Xclobber: clean X END_OF_FILE if test 512 -ne `wc -c <'makefile.v386'`; then echo shar: \"'makefile.v386'\" unpacked with wrong size! fi # end of 'makefile.v386' fi if test -f 'makefile.vat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile.vat'\" else echo shar: Extracting \"'makefile.vat'\" \(1396 characters\) sed "s/^X//" >'makefile.vat' <<'END_OF_FILE' X X# Replace the following line with the path to the linkkit subdirectory. XLINKKIT=/usr/linkkit X XCFLAGS = -O -Ml -DiAPX286 X XOBJS = asy.o X X# When make is executed, the object module is the only item that is built. X# Installation has to be requested. Xasy.o: asy.c \ X asy_conf.h \ X asy.h X cc $(CFLAGS) -I$(LINKKIT) -c asy.c X X# Install the object module in lib0. This is the location for third party X# device drivers. Don't bother trying to replace the Microport drivers. This X# library will link in first and do the replacement for you. Xinstall: asy.o X ar rv $(LINKKIT)/lib0 asy.o X X# Make the appropriate changes to the master and dfile. This action only needs X# to be performed once. Xmaster: X sed -e '/^asy.*/s//asy 36,35 ocrwis cot asy 0 5 2/' < $(LINKKIT)/cf/master > /tmp/asy$$ X mv /tmp/asy$$ $(LINKKIT)/cf/master X sed -e '/^asy.*/s//asy 0 2/' < $(LINKKIT)/cf/dfile.wini > /tmp/asy$$ X mv /tmp/asy$$ $(LINKKIT)/cf/dfile.wini X X# Make the devices with the correct names in /dev. This will kill the X# devices which Microport has provided. This step needs to be performed X# only once. Xdevices: X rm -f /dev/tty0 /dev/tty1 /dev/ttyM0 /dev/ttyM1 X mknod /dev/tty0 c 5 0 X mknod /dev/tty1 c 5 1 X mknod /dev/ttyM0 c 5 128 X mknod /dev/ttyM1 c 5 129 X X# Just for fun. Make a kernel Xkernel: X cd $(LINKKIT)/cf; make wini X X# And Oh boy, can't have a makefile without a clean Xclean: X rm -f asy.o X Xclobber: clean X END_OF_FILE if test 1396 -ne `wc -c <'makefile.vat'`; then echo shar: \"'makefile.vat'\" unpacked with wrong size! fi # end of 'makefile.vat' fi if test -f 'patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel.h'\" else echo shar: Extracting \"'patchlevel.h'\" \(37 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' Xrelease 1.00 release 1 patchlevel 00 END_OF_FILE if test 37 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi echo shar: End of shell archive. exit 0 -- Jim Murray encore!cloud9!jjmhome!jjm 2 Mohawk Circle harvard!m2c!jjmhome!jjm Westboro Mass 01581 jjm%jjmhome@m2c.m2c.org USA voice (508) 366-2813