summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-02-14 00:52:10 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-02-14 00:52:10 +0000
commit27d9bc313f809d04d8745ba88b29cc70a7ec68af (patch)
tree9da8ff1b2cb881505af63c883781216963c7f81e /sys
parent4c5853672ba862dc98bd5164f1fd23e14a14f3ea (diff)
Behave correctly in interrupt handlers if no tty has been allocated yet.
Prevents monkeys pounding on your serial terminal from panicing your kernel before getty gets spawned on the serial ports. dcm(4) looks safe from this problem from code inspection.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hp300/dev/apci.c29
-rw-r--r--sys/arch/hp300/dev/dca.c59
2 files changed, 55 insertions, 33 deletions
diff --git a/sys/arch/hp300/dev/apci.c b/sys/arch/hp300/dev/apci.c
index 796883e3ae3..ac545366ca4 100644
--- a/sys/arch/hp300/dev/apci.c
+++ b/sys/arch/hp300/dev/apci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apci.c,v 1.19 2005/02/12 18:01:08 miod Exp $ */
+/* $OpenBSD: apci.c,v 1.20 2005/02/14 00:52:09 miod Exp $ */
/* $NetBSD: apci.c,v 1.9 2000/11/02 00:35:05 eeh Exp $ */
/*-
@@ -489,7 +489,7 @@ apciintr(arg)
#define RCVBYTE() \
c = apci->ap_data; \
- if ((tp->t_state & TS_ISOPEN) != 0) \
+ if (tp != NULL && (tp->t_state & TS_ISOPEN) != 0) \
(*linesw[tp->t_line].l_rint)(c, tp)
for (;;) {
@@ -511,7 +511,8 @@ apciintr(arg)
apcieint(sc, lsr);
}
}
- if (iflowdone == 0 && (tp->t_cflag & CRTS_IFLOW) &&
+ if (iflowdone == 0 && tp != NULL &&
+ (tp->t_cflag & CRTS_IFLOW) &&
tp->t_rawq.c_cc > (TTYHOG / 2)) {
apci->ap_mcr &= ~MCR_RTS;
iflowdone = 1;
@@ -519,11 +520,13 @@ apciintr(arg)
break;
case IIR_TXRDY:
- tp->t_state &=~ (TS_BUSY|TS_FLUSH);
- if (tp->t_line)
- (*linesw[tp->t_line].l_start)(tp);
- else
- apcistart(tp);
+ if (tp != NULL) {
+ tp->t_state &=~ (TS_BUSY|TS_FLUSH);
+ if (tp->t_line)
+ (*linesw[tp->t_line].l_start)(tp);
+ else
+ apcistart(tp);
+ }
break;
default:
@@ -531,7 +534,7 @@ apciintr(arg)
return (claimed);
log(LOG_WARNING, "%s: weird interrupt: 0x%x\n",
sc->sc_dev.dv_xname, iir);
- /* fall through */
+ /* FALLTHROUGH */
case IIR_MLSC:
apcimint(sc, apci->ap_msr);
@@ -552,8 +555,6 @@ apcieint(sc, stat)
int c;
c = apci->ap_data;
- if ((tp->t_state & TS_ISOPEN) == 0)
- return;
#ifdef DDB
if ((sc->sc_flags & APCI_ISCONSOLE) && db_console && (stat & LSR_BI)) {
@@ -562,6 +563,9 @@ apcieint(sc, stat)
}
#endif
+ if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
+ return;
+
if (stat & (LSR_BI | LSR_FE)) {
c |= TTY_FE;
sc->sc_ferr++;
@@ -581,6 +585,9 @@ apcimint(sc, stat)
struct tty *tp = sc->sc_tty;
struct apciregs *apci = sc->sc_apci;
+ if (tp == NULL)
+ return;
+
if ((stat & MSR_DDCD) &&
(sc->sc_flags & APCI_SOFTCAR) == 0) {
if (stat & MSR_DCD)
diff --git a/sys/arch/hp300/dev/dca.c b/sys/arch/hp300/dev/dca.c
index dd56bbe17ae..71ccfc3e13f 100644
--- a/sys/arch/hp300/dev/dca.c
+++ b/sys/arch/hp300/dev/dca.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dca.c,v 1.24 2005/02/12 18:01:08 miod Exp $ */
+/* $OpenBSD: dca.c,v 1.25 2005/02/14 00:52:09 miod Exp $ */
/* $NetBSD: dca.c,v 1.35 1997/05/05 20:58:18 thorpej Exp $ */
/*
@@ -521,6 +521,7 @@ dcaintr(arg)
#ifdef DEBUG
dcaintrcount[code & IIR_IMASK]++;
#endif
+
switch (code & IIR_IMASK) {
case IIR_NOPEND:
return (1);
@@ -533,16 +534,18 @@ dcaintr(arg)
#ifdef KGDB
#define RCVBYTE() \
code = dca->dca_data; \
- if ((tp->t_state & TS_ISOPEN) == 0) { \
- if (code == FRAME_END && \
- kgdb_dev == makedev(dcamajor, unit)) \
- kgdb_connect(0); /* trap into kgdb */ \
- } else \
- (*linesw[tp->t_line].l_rint)(code, tp)
+ if (tp != NULL) { \
+ if ((tp->t_state & TS_ISOPEN) == 0) { \
+ if (code == FRAME_END && \
+ kgdb_dev == makedev(dcamajor, unit)) \
+ kgdb_connect(0); /* trap into kgdb */ \
+ } else \
+ (*linesw[tp->t_line].l_rint)(code, tp) \
+ }
#else
#define RCVBYTE() \
code = dca->dca_data; \
- if ((tp->t_state & TS_ISOPEN) != 0) \
+ if (tp != NULL && (tp->t_state & TS_ISOPEN) != 0) \
(*linesw[tp->t_line].l_rint)(code, tp)
#endif
RCVBYTE();
@@ -573,11 +576,13 @@ dcaintr(arg)
}
break;
case IIR_TXRDY:
- tp->t_state &=~ (TS_BUSY|TS_FLUSH);
- if (tp->t_line)
- (*linesw[tp->t_line].l_start)(tp);
- else
- dcastart(tp);
+ if (tp != NULL) {
+ tp->t_state &=~ (TS_BUSY|TS_FLUSH);
+ if (tp->t_line)
+ (*linesw[tp->t_line].l_start)(tp);
+ else
+ dcastart(tp);
+ }
break;
case IIR_RLS:
dcaeint(sc, dca->dca_lsr);
@@ -587,7 +592,7 @@ dcaintr(arg)
return (1);
log(LOG_WARNING, "%s: weird interrupt: 0x%x\n",
sc->sc_dev.dv_xname, code);
- /* fall through */
+ /* FALLTHROUGH */
case IIR_MLSC:
dcamint(sc);
break;
@@ -605,22 +610,28 @@ dcaeint(sc, stat)
int c;
c = dca->dca_data;
+
+#if defined(DDB) && !defined(KGDB)
+ if ((sc->sc_flags & DCA_ISCONSOLE) && db_console && (stat & LSR_BI)) {
+ Debugger();
+ return;
+ }
+#endif
+
+ if (tp == NULL)
+ return;
+
if ((tp->t_state & TS_ISOPEN) == 0) {
#ifdef KGDB
/* we don't care about parity errors */
if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) &&
- kgdb_dev == makedev(dcamajor, sc->sc_hd->hp_unit)
- && c == FRAME_END)
+ kgdb_dev == makedev(dcamajor, sc->sc_hd->hp_unit) &&
+ c == FRAME_END)
kgdb_connect(0); /* trap into kgdb */
#endif
return;
}
-#if defined(DDB) && !defined(KGDB)
- if ((sc->sc_flags & DCA_ISCONSOLE) && db_console && (stat & LSR_BI)) {
- Debugger();
- return;
- }
-#endif
+
if (stat & (LSR_BI | LSR_FE))
c |= TTY_FE;
else if (stat & LSR_PE)
@@ -642,6 +653,10 @@ dcamint(sc)
#ifdef DEBUG
dcamintcount[stat & 0xf]++;
#endif
+
+ if (tp == NULL)
+ return;
+
if ((stat & MSR_DDCD) &&
(sc->sc_flags & DCA_SOFTCAR) == 0) {
if (stat & MSR_DCD)