diff options
| author | thorpej <thorpej@NetBSD.org> | 2003-06-13 02:32:27 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2003-06-13 02:32:27 +0000 |
| commit | 76464bb996aaa0ac03a67c501e58a98ff3da7a15 (patch) | |
| tree | 7615ce2cc559775716cb328056e4c43d6e83d9ad /sys/dev | |
| parent | 3ef0e3947366f1ebebaf0a6812780b42cca2dee7 (diff) | |
* Don't wait for commands to drain when adjusting the queue length.
Instead, wait when it's really needed, when detaching. Project
draining from spruious wakeups.
* Don't flush the controller's cache when detaching; we can't do it
reliably, as the controller probably things the array drive no
longer exists. The cache is already flushed in ldclose() so this
should be no problem.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ld.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/sys/dev/ld.c b/sys/dev/ld.c index 2c8bd20a569..3d843a4c700 100644 --- a/sys/dev/ld.c +++ b/sys/dev/ld.c @@ -1,4 +1,4 @@ -/* $NetBSD: ld.c,v 1.23 2003/06/07 23:37:24 thorpej Exp $ */ +/* $NetBSD: ld.c,v 1.24 2003/06/13 02:32:27 thorpej Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.23 2003/06/07 23:37:24 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.24 2003/06/13 02:32:27 thorpej Exp $"); #include "rnd.h" @@ -157,25 +157,19 @@ ldattach(struct ld_softc *sc) int ldadjqparam(struct ld_softc *sc, int max) { - int s, rv; + int s; s = splbio(); sc->sc_maxqueuecnt = max; - if (sc->sc_queuecnt > max) { - sc->sc_flags |= LDF_DRAIN; - rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 30 * hz); - sc->sc_flags &= ~LDF_DRAIN; - } else - rv = 0; splx(s); - return (rv); + return (0); } int ldbegindetach(struct ld_softc *sc, int flags) { - int s, rv; + int s, rv = 0; if ((sc->sc_flags & LDF_ENABLED) == 0) return (0); @@ -184,8 +178,14 @@ ldbegindetach(struct ld_softc *sc, int flags) return (EBUSY); s = splbio(); + sc->sc_maxqueuecnt = 0; sc->sc_flags |= LDF_DETACH; - rv = ldadjqparam(sc, 0); + while (sc->sc_queuecnt > 0) { + sc->sc_flags |= LDF_DRAIN; + rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 0); + if (rv) + break; + } splx(s); return (rv); @@ -235,11 +235,18 @@ ldenddetach(struct ld_softc *sc) rnd_detach_source(&sc->sc_rnd_source); #endif + /* + * XXX We can't really flush the cache here, beceause the + * XXX device may already be non-existent from the controller's + * XXX perspective. + */ +#if 0 /* Flush the device's cache. */ if (sc->sc_flush != NULL) if ((*sc->sc_flush)(sc) != 0) printf("%s: unable to flush cache\n", sc->sc_dv.dv_xname); +#endif } /* ARGSUSED */ @@ -597,8 +604,10 @@ lddone(struct ld_softc *sc, struct buf *bp) biodone(bp); if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) { - if ((sc->sc_flags & LDF_DRAIN) != 0) + if ((sc->sc_flags & LDF_DRAIN) != 0) { + sc->sc_flags &= ~LDF_DRAIN; wakeup(&sc->sc_queuecnt); + } ldstart(sc); } } |
