*BSD News Article 37373


Return to BSD News archive

Xref: sserve comp.os.linux.development:18444 comp.os.linux.misc:28477 comp.os.386bsd.questions:14134 comp.os.386bsd.misc:3894 sci.electronics:82968
Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!msuinfo!caen!math.ohio-state.edu!howland.reston.ans.net!spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!athena.mit.edu!tytso
From: tytso@athena.mit.edu (Theodore Y. Ts'o)
Newsgroups: comp.os.linux.development,comp.os.linux.misc,comp.os.386bsd.questions,comp.os.386bsd.misc,sci.electronics
Subject: Re: 16550 detection
Date: 31 Oct 1994 21:25:11 GMT
Organization: Massachusetts Institute of Technology
Lines: 90
Message-ID: <TYTSO.94Oct31162517@dcl.mit.edu>
References: <CMETZ.94Oct30051603@itchy.inner.net>
	<SRA.94Oct30162124@rurha-pente.epilogue.com>
	<CMETZ.94Oct30192816@itchy.inner.net> <CyIzxz.97A@cuug.ab.ca>
NNTP-Posting-Host: dcl.mit.edu
In-reply-to: pepersb@cuug.ab.ca's message of Mon, 31 Oct 1994 07:10:46 GMT

In article <CyIzxz.97A@cuug.ab.ca> pepersb@cuug.ab.ca (Brad Pepers) writes:
>The current serial code checks for a 16550 by turning on the fifo's and
>then checking some bits that are supposed to tell you if the fifo's are
>on.  This sounds great and should work all the time right?  

This is indeed the documented way (if you read the National
Semiconductor datasheets) for testing to make sure that you have a
NS16550A, PC16550, PC16550C, or PC16550CF.  Basically, to make sure that
you have a 16550 that *doesn't* have the FIFO bug that the early 16550's
have.  Actually, very few of the buggy 16550's were actually produced,
and I think most of them went into early model PS/2's.  These days,
National Semicondutctor has started dropping the 'A' designation, with
PC16550, PC16550C, and PC16550CF's, which are just fine for use.  

So you don't necessarily need to panic if you see a chip that says
16550, instead of 16550A.  If it's one of the old, buggy chips, the
software test in Linux (and I'm pretty sure the same check is in the BSD
com drivers) will pick it up.  (Although you should beware if you see
someone offering to sell you a 16550 for cheap at a hamfest, or some
such.  New 16550's typically cost $12-$15 dollars.)

>But it seems some 16550 compatible chips sets don't work this way.  In
>the last couple of days I've loaded Linux on 2 systems that swear they
>use 16550's and seem to work fine when I use setserial to say the are
>16550's but are only recognized as 16450's by Linux.  Anyone know why?
>Anyone got a clue if there is another way to check for a 16550 chip?  I
>know it isn't required since setserial can fix things up but it would
>be nice to have Linux figure it out by itself.  I'm looking into
>finding our exactly what chips are being used.

What probably happened is those systems have cheasy internal modems that
claim to be "16550 compatible", which is a pure marketing lie.
Typically, the marketing literature will also babble about 1024 byte
FIFO's; that's the key tipoff.

What's happening is that these modems, instead of using an authentic
National Semicondutor part, or a more quality designed clone, is using a
cheasy UART which has a 1024 byte buffer, which otherwise looks like a
16450.  In particular, it doesn't set the bits in the Interrupt
Identification Register which tells OS's that you have a 16550A.  This
is just as well, because it does *not* have a transmit FIFO.  

Hence, you do *not* want to use setserial under Linux to force the
serial driver to think it's a 16550A UART, because it's not really a
16550A uart.  If you do, then when you are doing bulk transfers, the
serial driver will try to send 16 characters at once to the UART,
assuming that it has the transmit FIFO.  Since their chip does not have
the transmit FIFO, you will end up dropping characters.  

As far as taking advantage of the receive FIFO, the only thing which the
serial driver needs to do is to configure what the receive FIFO trigger
level should be.  If these cheasy UART's actually do something
automatically, then the serial driver will be able to take advantage of
the "1024 byte FIFO" without needing any changes, or even needing to set
the UART to be 16550A.  If, on the other hand, these cheasy UART's need
some other magic bits to be set, then someone's going to have to send me
the datasheets for them, since the serial driver isn't going to know how
to deal with them.  

The bottom line is that in all likelihood, the "1024 byte buffer" is
completely marketing noise.  Because of latency issues, you don't *want*
there to be 1024 bytes in the buffer before the kernel gets ahold of the
characters.  The 1024 byte buffer might be useful under MS-LOSS, if a
TSR turns interrupts off for a long time, and you don't want to lose
characters.  But under a real operating system, like Linux or *BSD, the
1024 byte buffer isn't terribly important anyway.  The 16 character FIFO
in the 16550 is plenty.  

						- Ted

P.S.  These cheasy UART's also have the problem of being hard to
autodetect, since they don't implement the loopback mode, which Linux
uses for testing to make sure that a serial UART is actually present.
So this test is skipped for COM 1--3, and Linux proceeds to try to
determine the irq of the port.  If that fails, then it is assumed that
the UART isn't there.  Unfortunately, the 8514/a graphics adaptor shares
the same ports as COM4, and if you skip the loopback mode test for COM4,
the automatic IRQ testing will screw up the 8514/a adaptor.  Therefore,
if you have one of these cheasy internal modems on COM4, Linux won't
find it; you have to use setserial to tell Linux about it manually.

P.P.S.  If you've gotten the idea that I don't like these cheasy
internal modems, you're right.  Trying to accomodate them has given me a
lot of headaches.  I usually try to pursuade people to get a real,
honest-to-goodness serial port, and then hook up an external modem to
the serial port.  That way, you can move the modem from machine to
machine, and you in general get a lot more flexibility.  However, if you
must get an internal modem, please please please do yourself a favor and
get one which uses a genuine National Semiconductor UART, and not one of
the cheasy imitations.