summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2008-11-23 14:02:06 +0000
committermav <mav@FreeBSD.org>2008-11-23 14:02:06 +0000
commiteffe067191474bd1bb58cca639534979e876c675 (patch)
treec62cd4bdb9eb96e7912e47ba61c538d2be163244
parent1142201df8c0741d9b787f4dbd27031ab5f93e60 (diff)
downloadFreeBSD-src-effe067191474bd1bb58cca639534979e876c675.zip
FreeBSD-src-effe067191474bd1bb58cca639534979e876c675.tar.gz
Improve detach handling: close races, flush queue.
-rw-r--r--sys/dev/mmc/mmcsd.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/sys/dev/mmc/mmcsd.c b/sys/dev/mmc/mmcsd.c
index 428d215..8e08b63 100644
--- a/sys/dev/mmc/mmcsd.c
+++ b/sys/dev/mmc/mmcsd.c
@@ -184,9 +184,10 @@ mmcsd_detach(device_t dev)
msleep(sc, &sc->sc_mtx, PRIBIO, "detach", 0);
MMCSD_UNLOCK(sc);
+ /* Flush the request queue. */
+ bioq_flush(&sc->bio_queue, NULL, ENXIO);
/* kill disk */
disk_destroy(sc->disk);
- /* XXX destroy anything in queue */
MMCSD_LOCK_DESTROY(sc);
@@ -212,9 +213,14 @@ mmcsd_strategy(struct bio *bp)
sc = (struct mmcsd_softc *)bp->bio_disk->d_drv1;
MMCSD_LOCK(sc);
- bioq_disksort(&sc->bio_queue, bp);
- wakeup(sc);
- MMCSD_UNLOCK(sc);
+ if (sc->running > 0) {
+ bioq_disksort(&sc->bio_queue, bp);
+ wakeup(sc);
+ MMCSD_UNLOCK(sc);
+ } else {
+ MMCSD_UNLOCK(sc);
+ biofinish(bp, NULL, ENXIO);
+ }
}
static daddr_t
@@ -380,18 +386,16 @@ mmcsd_task(void *arg)
device_t dev;
dev = sc->dev;
- while (sc->running) {
+ while (1) {
MMCSD_LOCK(sc);
do {
- bp = bioq_first(&sc->bio_queue);
+ if (sc->running == 0)
+ goto out;
+ bp = bioq_takefirst(&sc->bio_queue);
if (bp == NULL)
msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0);
- } while (bp == NULL && sc->running);
- if (bp)
- bioq_remove(&sc->bio_queue, bp);
+ } while (bp == NULL);
MMCSD_UNLOCK(sc);
- if (!sc->running)
- break;
if (bp->bio_cmd != BIO_READ && mmc_get_read_only(dev)) {
bp->bio_error = EROFS;
bp->bio_resid = bp->bio_bcount;
@@ -419,9 +423,8 @@ mmcsd_task(void *arg)
}
biodone(bp);
}
-
+out:
/* tell parent we're done */
- MMCSD_LOCK(sc);
sc->running = -1;
wakeup(sc);
MMCSD_UNLOCK(sc);
OpenPOWER on IntegriCloud