diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-02-14 00:52:10 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-02-14 00:52:10 +0000 |
commit | 27d9bc313f809d04d8745ba88b29cc70a7ec68af (patch) | |
tree | 9da8ff1b2cb881505af63c883781216963c7f81e /sys/arch/hp300/dev | |
parent | 4c5853672ba862dc98bd5164f1fd23e14a14f3ea (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/arch/hp300/dev')
-rw-r--r-- | sys/arch/hp300/dev/apci.c | 29 | ||||
-rw-r--r-- | sys/arch/hp300/dev/dca.c | 59 |
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) |