diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-04-27 21:34:19 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-04-27 21:34:19 +0000 |
commit | 56ea603a4ddd37181a88c59c9014ae7d102c67e2 (patch) | |
tree | 581c4ba940acf5649dd3c37b3827dbcc4a425938 /sys | |
parent | e50903f8ae8397fe1d1ac92245784339d0e72bed (diff) |
In osiop_checkintr(), bail out early and do not claim the interrupt for
``can't happen'' situations (which happen sometimes on mvme88k), rather
than inadvertently dereference NULL pointers and panic.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/osiop.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/sys/dev/ic/osiop.c b/sys/dev/ic/osiop.c index e54b4a5af07..2eb18f4d003 100644 --- a/sys/dev/ic/osiop.c +++ b/sys/dev/ic/osiop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: osiop.c,v 1.23 2004/12/27 15:53:13 miod Exp $ */ +/* $OpenBSD: osiop.c,v 1.24 2005/04/27 21:34:18 miod Exp $ */ /* $NetBSD: osiop.c,v 1.9 2002/04/05 18:27:54 bouyer Exp $ */ /* @@ -1159,9 +1159,11 @@ osiop_checkintr(sc, istat, dstat, sstat0, status) if (dstat & OSIOP_DSTAT_SIR && intcode == A_ok) { /* Normal completion status, or check condition */ struct osiop_tinfo *ti; - if (acb == NULL) + if (acb == NULL) { printf("%s: COMPLETE with no active command?\n", sc->sc_dev.dv_xname); + return (0); + } #ifdef OSIOP_DEBUG if (osiop_read_4(sc, OSIOP_DSA) != dsdma->dm_segs[0].ds_addr + acb->dsoffset) { @@ -1207,9 +1209,11 @@ osiop_checkintr(sc, istat, dstat, sstat0, status) return (1); } if (dstat & OSIOP_DSTAT_SIR && intcode == A_int_syncmsg) { - if (acb == NULL) + if (acb == NULL) { printf("%s: Sync message with no active command?\n", sc->sc_dev.dv_xname); + return (0); + } target = acb->xs->sc_link->target; if (ds->msgbuf[1] == MSG_EXTENDED && ds->msgbuf[2] == MSG_EXT_SDTR_LEN && @@ -1250,9 +1254,11 @@ osiop_checkintr(sc, istat, dstat, sstat0, status) #ifdef OSIOP_DEBUG osiopphmm++; #endif - if (acb == NULL) + if (acb == NULL) { printf("%s: Phase mismatch with no active command?\n", sc->sc_dev.dv_xname); + return (0); + } if (acb->datalen > 0) { int adjust = (dfifo - (dbc & 0x7f)) & 0x7f; if (sstat1 & OSIOP_SSTAT1_ORF) @@ -1321,9 +1327,11 @@ osiop_checkintr(sc, istat, dstat, sstat0, status) } if (sstat0 & OSIOP_SSTAT0_STO) { /* Select timed out */ - if (acb == NULL) + if (acb == NULL) { printf("%s: Select timeout with no active command?\n", sc->sc_dev.dv_xname); + return (0); + } #ifdef OSIOP_DEBUG if (osiop_read_1(sc, OSIOP_SBCL) & OSIOP_BSY) { printf("ACK! osiop was busy at timeout: " @@ -1631,9 +1639,11 @@ osiop_checkintr(sc, istat, dstat, sstat0, status) } if (dstat & OSIOP_DSTAT_SIR && intcode == A_int_msgin) { /* Unrecognized message in byte */ - if (acb == NULL) + if (acb == NULL) { printf("%s: Bad message-in with no active command?\n", sc->sc_dev.dv_xname); + return (0); + } printf("%s: Unrecognized message in data " "sfbr %x msg %x sbcl %x\n", sc->sc_dev.dv_xname, osiop_read_1(sc, OSIOP_SFBR), ds->msgbuf[1], |