Igloopatch

John Welch jjw at igloo.UUCP
Thu Oct 20 12:18:43 AEST 1988


#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--   1 root     sys         6344 Oct 18 19:55 16550.c
#
echo 'x - 16550.c'
if test -f 16550.c; then echo 'shar: not overwriting 16550.c'; else
sed 's/^X//' << '________This_Is_The_END________' > 16550.c
X/******************************************************************************
X                            16550 
X      a utility that iturns on the FIFO of a NS 16550 chip
X               by John Welch, of Igloo Computers
X                     Public Domain Software
X Hobbyists, feel free to use, abuse, pirate and re-distribute this program.
X       Commercial use prohibited without consent of the author.
X                   Send fan mail to jjw at igloo
X                  Send flames to jjw@/dev/null
X******************************************************************************/
X#include <sys/types.h>
X#include <sys/io_op.h>
X#include <fcntl.h>
X
Xint fd;
Xvoid outb();
Xextern int errno;
X
Xmain() 
X{
X
X
X/*
X		I've waded through the NS 16550 docs for several days now,
X	and what follows seems accurate enough.
X	At any rate, the basic idea is that a 16550 with FIFO enabled
X	has (*FINALLY!*) cured igloo's problems with losing newsfeeds. I
X	thought I'd make this available to the net in the hopes that it may
X	help other people who've been singing the 'microport lost character
X	blues.' As microport has been unable to cure this, we finally fixed
X	it ourselves. By the way, if you aren't tech-y, this may bore you
X	to death. I've got it written to patch tty0 and tty1, and since on a
X	16450 or earlier this register isn't writable it should cause no
X	problems. Just un-shar it by typing
X		sh 16550.shar
X	and compile this with
X		cc -o 16550 -O 16550.c
X	It might be a good idea to chmod this to 700, to prevent users from
X	flushing the buffers on you. Adding this to the inittab file or some
X	such place should be all thats needed. Run it once at boot-up and
X	forget it.
X		A bit of history here: Microport's serial port drivers are
X	brain-dead. Apparently the problem is with the high-water mark in
X	the kernel, and so it's *not* fixable with new drivers. What this means
X	is that you lose characters sometimes. It is particularly noticable
X	while doing a 9600-baud newsfeed on one serial line while another
X	user on the other line is cat-ing a text file at 300 baud. Usually
X	when this happens, you get many errors during the newsfeed and as
X	often as not you lose the feed altogether. Microport has been told of
X	this problem many times, and they've piddled and fuddled and moped
X	around trying to fix it. At first they said we should get faster
X	hardware because an 8Mhz AT couldn't handle 9600 baud. Fine, we found
X	a place that loaned us a 20Mhz 0-wait 4Mbyte 386 board for a weekend.
X	Guess what??? The problem was just as bad as before. Then they sent
X	us  new driver to install, which did not help the problem. They then
X	suggested that we need a smart serial card, to the tune of around
X	$1500 or so. They think that 9600 baud cannot be done on these machines.
X	That's bull-squat, folks! XENIX does 9600 baud just fine. Microport is
X	unable and unwilling to fix this problem. We had to explore alternate
X	ways of doing it ourselves, preferrably without costing us hobbyists
X	an arm and a leg. We feel we've found an acceptable solution with the
X	16550 UART chip.
X		The 16550 is a half-way step between a 'smart' serial card
X	and the usual 16450-type 'dumb' card. Using the FIFOs in the 16550
X	can not only prevent lost characters, but can result in more efficient
X	CPU utilization, with less time wasted in processor overhead to read
X	each character sent. It does this by a device called a FIFO buffer, a
X	First-In, First-Out scheme. When receiving characters, the 16550 will
X	only interrupt the CPU when one of two events happens: When enough
X	characters have been received (you can define 'enough' to be 1, 4, 8
X	or 14) or when at least 1 character has been received and there has
X	not been another character come through for 4 times the time 'width'
X	of a character. In this manner, when the CPU finally gets interrupted,
X	much more data can be dumped to the CPU at once, cutting down on all
X	the overhead involved in context-swiching and so forth.
X		In addition, if the CPU takes too long to read the FIFO, the
X	16550 will send its own flow-control to throttle back the incoming
X	data, preventing buffer over-runs that have plagued microport from day
X	one.
X		The 16550 chip is a drop-in replacement for the 16450, and it
X	costs about $25 or so (not much more than the 16450). With this chip
X	and a trivial amount of software, you can not only cure microports
X	brain-dead serial device driver problems, but you can also enjoy most
X	of the benefits of a 'smart' card with very little cost.
X		What follows is an explaination of what this program does and
X	why it does it. If you have multi-port 'dumb' boards with 8250's,
X	16450's or whatever, you *should* be able to replace those chips with
X	16550s and modify this program to set (base+2) for each port.
X		tty0's base address is 3f8. The FIFO control register is at
X	base+2 (3fa). The byte written at this address is defined as follows:
X
X	 Bits 7 & 6 define at what level the 16550 interrupts the CPU. 11 is 14
X	bytes deep, 10 is 8 bytes deep, 01 is 4 bytes deep and 00 is 1 byte deep.
X
X	 Bits 5 & 4 are not used, so I set them to 00.
X
X	 Bit 3 defines the performance of some pins that are not used on the
X	16450, so it's not likely to be of consequence to anything we do. I've
X	chosen to keep them performing the way a 16450 would, setting this bit
X	0.
X	 Bit 2 clears and resets the transmit FIFO.
X	 Bit 1 clears and resets the Receive FIFO.
X	 Bit 0 turns the FIFO buffering on.
X		To turn on the FIFO at tty1 to a 4-byte level, one should
X	write a 0x47 to port 0x2fa. To set tty0 at the maximum FIFO level,
X	send 0xc7 to port 0x3fa. To disable FIFOs at tty1 send 0 to 0x2fa.
X*/
X
X
X    if ((fd = open("/dev/mem",O_RDWR)) == -1) /* open memory device for read/write */
X    {
X        perror("Open /dev/mem");
X        exit(1);
X    }
X
X
X    outb(0x3fa,0x87); /* this turns on tty0's FIFO, 8 characters deep */
X    outb(0x2fa,0x87); /* this turns on tty1's FIFO, 8 characters deep */
X
X    close(fd); /* all done setting up FIFOs. */
X}
X
X
Xvoid outb(portno, data)
Xint portno;
Xunsigned char data;
X{
X    io_op_t  iop;
X
X    iop.io_port = portno;
X    iop.io_byte = data;
X    errno = 0; /* clear error indicator */
X    ioctl(fd, IOCIOP_WB, &iop); /* write the data to that port */
X    if (errno)
X	printf("Error setting port %04x\n",portno);
X        /* send to stdout so they can re-direct easier */
X}
X
________This_Is_The_END________
if test `wc -l < 16550.c` -ne 138; then
	echo 'shar: 16550.c was damaged during transit (should have been 138 bytes)'
fi
fi		; : end of overwriting check
exit 0
-- 
==========================================================================
  John Welch                                <backbone>!jjw at igloo
 "Oh, reality - it's not for me, and it makes me laugh,
  but fantasy world, and those Disney girls... I'm coming back!"



More information about the Comp.unix.microport mailing list