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, &params);
                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, &params);
                }
@@ -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