While investigating the serial console problem on the v445 (see my
previous mail), I noticed that Linux has an additional checks for
detecting the broken st16550 chips that don't have a working FIFO.  It
has a comment that specifically mentions the "Motorola 8xxx DUART" as
being falsely detected as an st16550.  With the diff below, the serial
port on my socppc (MPC8347) changes from:

  com0 at obio0 offset 0x04500 ivec 9: st16650, no working fifo

to:

  com0 at obio0 offset 0x04500 ivec 9: ns16550a, 16 byte fifo

The FIFO appears to work just fine.

The second serial port on the v445 changes as well, from:

  com1 at ebus1 addr fffff8-ffffff ivec 0x78a: st16650, no working fifo

to:

  com1 at ebus1 addr fffff8-ffffff ivec 0x78a: ns16550a, 16 byte fifo

I'm not currently in a position to test this port, but I highly doubt
Sun used a broken st16650 in that machine.

I'd really appreciate if people could test this diff if they have a
serial port that shows up as "st16650, no working fifo".  Please check
if it changes to a ns16550a after applying this diff and whether the
serial port still functions properly.

Thanks,

Mark


Index: com.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/com.c,v
retrieving revision 1.149
diff -u -p -r1.149 com.c
--- com.c       12 May 2012 18:02:33 -0000      1.149
+++ com.c       19 Aug 2012 16:47:58 -0000
@@ -1627,7 +1627,10 @@ com_attach_subr(struct com_softc *sc)
        if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
                bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
                if (bus_space_read_1(iot, ioh, com_efr) == 0) {
-                       sc->sc_uarttype = COM_UART_ST16650;
+                       bus_space_write_1(iot, ioh, com_efr, EFR_CTS);
+                       if (bus_space_read_1(iot, ioh, com_efr) != 0)
+                               sc->sc_uarttype = COM_UART_ST16650;
+                       bus_space_write_1(iot, ioh, com_efr, 0);
                } else {
                        bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
                        if (bus_space_read_1(iot, ioh, com_efr) == 0)

Reply via email to