From 27d9bc313f809d04d8745ba88b29cc70a7ec68af Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Mon, 14 Feb 2005 00:52:10 +0000 Subject: 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. --- sys/arch/hp300/dev/apci.c | 29 ++++++++++++++--------- 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) -- cgit v1.2.3