Hi everyone,

I'd like to follow up a post I made to bugs last year entitled "5.4 with Digi serial board drops characters (silo overflow)". Link http://openbsd-archive.7691.n7.nabble.com/5-4-with-Digi-serial-board-drops-characters-silo-overflow-td244124.html

I have since had a chance to re-visit the issue under OpenBSD 5.7 (I suspect 5.8 still has the same issue) and made some progress wrt what's going on. It would appear that it's simply a matter of the serial FIFO buffer length being zero when it should be much larger. Here is a snippet of relevant dmesg output:

com4 at puc0 port 0 apic 8 int 16: ns16550a, 16 byte fifo
com4: probed fifo depth: 0 bytes

Now there are a number of problems as I see it. The first line shows a 16550a and a 16 byte FIFO. The Digi we are using is the 8 port Neo PCIe. It claims to be 16C850 compatible from which we can infer a 128 byte FIFO. So first thing is the correct chip isn't being detected. Still, I'm guessing the Digi chip is 16550a backwards compatible so in any case this should still work.

The second line shows the probed FIFO depth being zero. Looking through the kernel code (/usr/src/sys/dev/ic/com.c - I'm actually looking at 5.7 but from a quick look it appears that 5.8 might be identical) if the probed depth (zero) is less than the 16 byte above value the shorter of the two is used, ie. zero.

        /* For safety, always use the smaller value. */
        if (sc->sc_fifolen > len) {
                printf("%s: probed fifo depth: %d bytes\n",
                    sc->sc_dev.dv_xname, len);
                sc->sc_fifolen = len;
        }

A 'zero' FIFO explains why I'm getting dropped characters when I run a couple of ports up at speeds of 19k2 or more.

Looking through the com.c file there is mention of the 16850 chip, but that code appears to be commented out with the comment /* until com works with large FIFOs */ Hmm... Google shows the OpenBSD 2.3 release changes including "Add support for the XR16850 serial chip (128 byte fifos)". So I guess something has happened between OpenBSD 2.3 and OpenBSD 5.7 to warrant its removal.

Assuming for now that we can make do with just 16 byte FIFOs I thought I'd try a hack to see if I could get it to work. Here is my hack:

        /* For safety, always use the smaller value. */
        if (sc->sc_fifolen > len) {
                printf("%s: probed fifo depth: %d bytes\n",
                    sc->sc_dev.dv_xname, len);

                /* MJV modification 17-Dec-2015 */
                /* Probe doesn't work on Digi Neo 8 PCIe so */
                /* don't rely on it */

                if (len == 0)
                        printf("%s: override, using %d byte FIFO\n",
                                sc->sc_dev.dv_xname, sc->sc_fifolen);
                else
                        sc->sc_fifolen = len;
        }

Well I tried it out and it works; no more missing serial characters. Unfortunately this code change is a real hack and would potentially mess up your system if you had other serial boards that don't have a FIFO (but are somehow detected as having a FIFO).

I would think a better fix would be to fix the 16850 sections (and make large FIFOs work???) but this sounds like a potential can of worms otherwise I would have tried it.

So maybe this hack is useful to anyone out there with the same Digi Neo-8 PCIe card and who is also having problems with dropped characters.

If anyone is maintaining the serial code, and wishes to fix it properly I'm happy to test out the changes on the card here.

Also thoughts for a more elegant hack would be welcome.

Regards,

-Martin


--
R A Ward Ltd. | We take the privacy of our customers seriously.
Christchurch  | All sensitive E-Mail attachments MUST be encrypted.
New Zealand

Reply via email to