Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Fix hang up writing /dev/console rarely in specif...
details: https://anonhg.NetBSD.org/src/rev/817888ef8f6e
branches: trunk
changeset: 372563:817888ef8f6e
user: knakahara <knakahara%NetBSD.org@localhost>
date: Thu Dec 08 09:08:49 2022 +0000
description:
Fix hang up writing /dev/console rarely in specific environments.
Some BMC seems to require these syncronous operations. If not,
it does not send transmit completion interrupts for some reason.
diffstat:
sys/dev/ic/com.c | 36 +++++++++++++++++++++++++++++-------
1 files changed, 29 insertions(+), 7 deletions(-)
diffs (91 lines):
diff -r 64bbe61483ce -r 817888ef8f6e sys/dev/ic/com.c
--- a/sys/dev/ic/com.c Thu Dec 08 08:14:28 2022 +0000
+++ b/sys/dev/ic/com.c Thu Dec 08 09:08:49 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: com.c,v 1.380 2022/12/03 11:28:38 skrll Exp $ */
+/* $NetBSD: com.c,v 1.381 2022/12/08 09:08:49 knakahara Exp $ */
/*-
* Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.380 2022/12/03 11:28:38 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.381 2022/12/08 09:08:49 knakahara Exp $");
#include "opt_com.h"
#include "opt_ddb.h"
@@ -206,6 +206,28 @@
.cn_pri = CN_NORMAL
};
+#define CSR_WRITE_1_SYNC(r, o, v) do { \
+ CSR_WRITE_1(r, o, v); \
+ switch(o) { \
+ case COM_REG_IER: \
+ (void)CSR_READ_1(r, COM_REG_IIR); \
+ break; \
+ case COM_REG_TXDATA: \
+ (void)CSR_READ_1(r, COM_REG_TLR); \
+ break; \
+ } \
+ } while(0)
+#define CSR_WRITE_MULTI_SYNC(r, o, p, n) do { \
+ CSR_WRITE_MULTI(r, o, p, n); \
+ switch(o) { \
+ case COM_REG_IER: \
+ (void)CSR_READ_1(r, COM_REG_IIR); \
+ break; \
+ case COM_REG_TXDATA: \
+ (void)CSR_READ_1(r, COM_REG_TLR); \
+ break; \
+ } \
+ } while(0)
const struct cdevsw com_cdevsw = {
.d_open = comopen,
@@ -1961,7 +1983,7 @@
/* Enable transmit completion interrupts if necessary. */
if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
SET(sc->sc_ier, IER_ETXRDY);
- CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
+ CSR_WRITE_1_SYNC(regsp, COM_REG_IER, sc->sc_ier);
}
/* Output the first chunk of the contiguous buffer. */
@@ -1971,7 +1993,7 @@
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
- CSR_WRITE_MULTI(regsp, COM_REG_TXDATA, sc->sc_tba, n);
+ CSR_WRITE_MULTI_SYNC(regsp, COM_REG_TXDATA, sc->sc_tba, n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
@@ -2359,7 +2381,7 @@
CLR(sc->sc_ier, IER_ERXRDY);
break;
}
- CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
+ CSR_WRITE_1_SYNC(regsp, COM_REG_IER, sc->sc_ier);
}
} else {
if ((iir & (IIR_RXRDY|IIR_TXRDY)) == IIR_RXRDY) {
@@ -2443,14 +2465,14 @@
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
- CSR_WRITE_MULTI(regsp, COM_REG_TXDATA, sc->sc_tba, n);
+ CSR_WRITE_MULTI_SYNC(regsp, COM_REG_TXDATA, sc->sc_tba, n);
sc->sc_tbc -= n;
sc->sc_tba += n;
} else {
/* Disable transmit completion interrupts if necessary. */
if (ISSET(sc->sc_ier, IER_ETXRDY)) {
CLR(sc->sc_ier, IER_ETXRDY);
- CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
+ CSR_WRITE_1_SYNC(regsp, COM_REG_IER, sc->sc_ier);
}
if (sc->sc_tx_busy) {
sc->sc_tx_busy = 0;
Home |
Main Index |
Thread Index |
Old Index