summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2009-03-29 01:02:36 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2009-03-29 01:02:36 +0000
commit39de1898b28cee31d6f85151bef7c97ed717c251 (patch)
tree8ed98d83694bebfb0168f325c95b4971f8bd4992 /sys
parentd850dd2bb32de14e6aafe432fdc04f9468fb454c (diff)
fix a small race in mfi_mgmt between the checking of a ccbs completion and
the sleep waiting for the completion. it is possible to get the interrupt completing the command just before the tsleep, which will never get a wakeup because the interrupt with the wakeup has already happened.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/mfi.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index 6afdd503868..43e75445df2 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.89 2009/02/16 21:19:06 miod Exp $ */
+/* $OpenBSD: mfi.c,v 1.90 2009/03/29 01:02:35 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -1163,6 +1163,7 @@ mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len,
struct mfi_ccb *ccb;
struct mfi_dcmd_frame *dcmd;
int rv = 1;
+ int s;
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt %#x\n", DEVNAME(sc), opc);
@@ -1199,11 +1200,13 @@ mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len,
if (mfi_poll(ccb))
goto done;
} else {
+ s = splbio();
mfi_post(sc, ccb);
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt sleeping\n", DEVNAME(sc));
while (ccb->ccb_state != MFI_CCB_DONE)
tsleep(ccb, PRIBIO, "mfi_mgmt", 0);
+ splx(s);
if (ccb->ccb_flags & MFI_CCB_F_ERR)
goto done;