Path: utzoo!utgpu!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!agate!labrea!decwrl!hplabs!motsj1!mcdchg!ddsw1!igloo!jjw From: jjw@igloo.UUCP (John Welch) Newsgroups: comp.unix.microport Subject: Re: Igloopatch Keywords: serial port relief Message-ID: <1059@igloo.UUCP> Date: 20 Oct 88 02:18:43 GMT References: <1058@igloo.UUCP> Reply-To: jjw@igloo.UUCP (John Welch) Organization: igloo, Northbrook, IL Lines: 165 #--------------------------------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@igloo X Send flames to jjw@/dev/null X******************************************************************************/ X#include X#include X#include 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 !jjw@igloo "Oh, reality - it's not for me, and it makes me laugh, but fantasy world, and those Disney girls... I'm coming back!"