diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-04-30 03:13:44 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-04-30 03:13:44 +0000 |
commit | f908dd4c32f61656adde01e2f9c24e9a87cf2ab8 (patch) | |
tree | 9e7d675f599ca731b3b8ee932d4c7a3326d3c339 /sys | |
parent | a98adcf0fac52389e6a5e24a622ff56d2de11f19 (diff) |
- Interrupt handler now checks shared interrupt source and protects
the interrupt handler from NULL pointer dereference which was caused
by odd status word value. The status word can return 0xffffffff if the
cable is unplugged while Rx/Tx/auto-negotiation is in progress.
From FreeBSD
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_sk.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c index 5b46aa1f762..d5f4bf44913 100644 --- a/sys/dev/pci/if_sk.c +++ b/sys/dev/pci/if_sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sk.c,v 1.102 2006/04/30 02:28:49 brad Exp $ */ +/* $OpenBSD: if_sk.c,v 1.103 2006/04/30 03:13:43 brad Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -2216,18 +2216,17 @@ sk_intr(void *xsc) u_int32_t status; int claimed = 0; + status = CSR_READ_4(sc, SK_ISSR); + if (status == 0 || status == 0xffffffff) + return (0); + if (sc_if0 != NULL) ifp0 = &sc_if0->arpcom.ac_if; if (sc_if1 != NULL) ifp1 = &sc_if1->arpcom.ac_if; - for (;;) { - status = CSR_READ_4(sc, SK_ISSR); - DPRINTFN(2, ("sk_intr: status=%#x\n", status)); - - if (!(status & sc->sk_intrmask)) - break; - + status &= sc->sk_intrmask; + if ((status & sc->sk_intrmask) != 0) { claimed = 1; /* Handle receive interrupts first. */ |