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.