diff --git a/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c b/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c index ae8459713003..96d20ceb21f4 100644 --- a/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c +++ b/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c @@ -221,6 +221,9 @@ aju_cons_write(char ch) * disconnection. * * XXXRW: The polling delay may require tuning. + * + * XXXRW: Notice the inherent race with hardware: in clearing the + * bit, we may race with hardware setting the same bit. */ v = aju_cons_control_read(); if (v & ALTERA_JTAG_UART_CONTROL_AC) { diff --git a/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c b/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c index ad5b8a41bdc5..dd46ea04038c 100644 --- a/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c +++ b/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c @@ -65,9 +65,9 @@ static struct ttydevsw aju_ttydevsw = { /* * When polling for the AC bit, the number of times we have to not see it - * before assuming JTAG has disappeared on us. By default, one second. + * before assuming JTAG has disappeared on us. By default, two seconds. */ -#define AJU_JTAG_MAXMISS 5 +#define AJU_JTAG_MAXMISS 10 /* * Polling intervals for input/output and JTAG connection events. @@ -255,6 +255,22 @@ aju_handle_output(struct altera_jtag_uart_softc *sc, struct tty *tp) if (ttydisc_getc(tp, &ch, sizeof(ch)) != sizeof(ch)) panic("%s: ttydisc_getc", __func__); AJU_LOCK(sc); + + /* + * XXXRW: There is a slight race here in which we test + * for writability, drop the lock, get the character + * from the tty layer, re-acquire the lock, and then + * write. It's possible for other code -- + * specifically, the low-level console -- to have + * written in the mean time, which might mean that + * there is no longer space. The BERI memory bus will + * cause this write to block, wedging the processor + * until space is available -- which could be a while + * if JTAG is not attached! + * + * The 'easy' fix is to drop the character if WSPACE + * has become unset. Not sure what the 'hard' fix is. + */ aju_data_write(sc, ch); } else { /*