Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Avoid a race condition that could allow a removab...
details: https://anonhg.NetBSD.org/src/rev/b0a57971ff19
branches: trunk
changeset: 553920:b0a57971ff19
user: briggs <briggs%NetBSD.org@localhost>
date: Wed Oct 22 23:59:00 2003 +0000
description:
Avoid a race condition that could allow a removable controller (such as
a compact flash card) to lock the atabus thread if it gets detached during
the probe process.
diffstat:
sys/dev/ic/wdc.c | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
diffs (80 lines):
diff -r 43b0e6f1f6d3 -r b0a57971ff19 sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c Wed Oct 22 23:57:04 2003 +0000
+++ b/sys/dev/ic/wdc.c Wed Oct 22 23:59:00 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdc.c,v 1.143 2003/10/15 20:29:26 bouyer Exp $ */
+/* $NetBSD: wdc.c,v 1.144 2003/10/22 23:59:00 briggs Exp $ */
/*
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.143 2003/10/15 20:29:26 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.144 2003/10/22 23:59:00 briggs Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@@ -268,8 +268,7 @@
chp->ch_flags |= WDCF_TH_RUN;
splx(s);
atabusconfig(atabus_sc);
- for(;;)
- {
+ while (!(chp->ch_flags & WDCF_SHUTDOWN)) {
s = splbio();
chp->ch_flags &= ~WDCF_TH_RUN;
tsleep(&chp->thread, PRIBIO, "atath", 0);
@@ -313,7 +312,7 @@
struct atabus_softc *atabus_sc;
{
struct channel_softc *chp = atabus_sc->sc_chan;
- int ctrl_flags, i, error;
+ int ctrl_flags, i, error, need_delref = 0;
struct ataparams params;
struct atabus_initq *atabus_initq = NULL;
u_int8_t st0, st1;
@@ -321,9 +320,9 @@
if ((error = wdc_addref(chp)) != 0) {
aprint_error("%s: unable to enable controller\n",
chp->wdc->sc_dev.dv_xname);
- config_pending_decr();
- return;
+ goto out;
}
+ need_delref = 1;
if (__wdcprobe(chp, 0) == 0)
/* If no drives, abort attach here. */
@@ -383,11 +382,20 @@
if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
continue;
+ /* Shortcut in case we've been shutdown */
+ if (chp->ch_flags & WDCF_SHUTDOWN)
+ goto out;
+
/* issue an identify, to try to detect ghosts */
error = ata_get_params(&chp->ch_drive[i],
AT_WAIT | AT_POLL, ¶ms);
if (error != CMD_OK) {
tsleep(&atabus_sc, PRIBIO, "atacnf", mstohz(1000));
+
+ /* Shortcut in case we've been shutdown */
+ if (chp->ch_flags & WDCF_SHUTDOWN)
+ goto out;
+
error = ata_get_params(&chp->ch_drive[i],
AT_WAIT | AT_POLL, ¶ms);
}
@@ -549,7 +557,8 @@
wakeup(&atabus_initq_head);
config_pending_decr();
- wdc_delref(chp);
+ if (need_delref)
+ wdc_delref(chp);
}
Home |
Main Index |
Thread Index |
Old Index