On the Sun Fire V445, I'm seeing garbage on the serial line when:
1) The machine gets to the very end of the boot sequence just before
it prints:
OpenBSD/sparc64 (v445.openbsd.org) (console)
login:
2) When I reboot the machine.
In the latter case in fact I get only garbage until I reset the
machine. Seriously annoying since it makes a simple reboot a serious
pain and doesn't allow me to interect with OBP after a halt.
Now on this machine we have:
com0 at ebus1 addr c2c000-c2c007 ivec 0x787: st16650, 32 byte fifo
com0: console
It turns out that the st16650 is one of those chips for which we
enable "sleep mode" when the serial line is closed. I guess that
makes sense for normal serial lines; if no process has the line open
we're not interested in anything that happens on the line. But if
this is the serial console that isn't true. The kernel will try to
print stuff on the console and on sparc64 machines the firmware will
print stuff too.
So here is a diff that skips the sleep mode stuff if the
COM_HW_CONSOLE flag is set. This fixes the problems I see on the
V445.
ok?
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 15:44:36 -0000
@@ -540,26 +540,28 @@ compwroff(struct com_softc *sc)
bus_space_write_1(iot, ioh, com_fifo,
FIFO_RCV_RST | FIFO_XMT_RST);
- switch (sc->sc_uarttype) {
- case COM_UART_ST16650:
- case COM_UART_ST16650V2:
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
- bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
- bus_space_write_1(iot, ioh, com_lcr, 0);
- break;
- case COM_UART_TI16750:
- bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
- break;
+ if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
+ switch (sc->sc_uarttype) {
+ case COM_UART_ST16650:
+ case COM_UART_ST16650V2:
+ bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
+ bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
+ bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
+ bus_space_write_1(iot, ioh, com_lcr, 0);
+ break;
+ case COM_UART_TI16750:
+ bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
+ break;
#ifdef COM_PXA2X0
- case COM_UART_PXA2X0:
- bus_space_write_1(iot, ioh, com_ier, 0);
+ case COM_UART_PXA2X0:
+ bus_space_write_1(iot, ioh, com_ier, 0);
#ifdef __zaurus__
- if (ISSET(sc->sc_hwflags, COM_HW_SIR))
- scoop_set_irled(0);
+ if (ISSET(sc->sc_hwflags, COM_HW_SIR))
+ scoop_set_irled(0);
#endif
- break;
+ break;
#endif
+ }
}
}