svn commit: r185201 - head/sys/dev/mmc
Alexander Motin
mav at FreeBSD.org
Sun Nov 23 06:02:06 PST 2008
Author: mav
Date: Sun Nov 23 14:02:06 2008
New Revision: 185201
URL: http://svn.freebsd.org/changeset/base/185201
Log:
Improve detach handling: close races, flush queue.
Modified:
head/sys/dev/mmc/mmcsd.c
Modified: head/sys/dev/mmc/mmcsd.c
==============================================================================
--- head/sys/dev/mmc/mmcsd.c Sun Nov 23 13:03:44 2008 (r185200)
+++ head/sys/dev/mmc/mmcsd.c Sun Nov 23 14:02:06 2008 (r185201)
@@ -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);
More information about the svn-src-all
mailing list