Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Allow for draining/adjusting the queue.
details: https://anonhg.NetBSD.org/src/rev/b209f62a2d8b
branches: trunk
changeset: 503279:b209f62a2d8b
user: ad <ad%NetBSD.org@localhost>
date: Sun Feb 04 17:15:37 2001 +0000
description:
Allow for draining/adjusting the queue.
diffstat:
sys/dev/ld.c | 68 +++++++++++++++++++++++++++++++++++++++++---------------
sys/dev/ldvar.h | 12 +++++----
2 files changed, 56 insertions(+), 24 deletions(-)
diffs (167 lines):
diff -r c7b57076332d -r b209f62a2d8b sys/dev/ld.c
--- a/sys/dev/ld.c Sun Feb 04 17:05:11 2001 +0000
+++ b/sys/dev/ld.c Sun Feb 04 17:15:37 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ld.c,v 1.6 2001/01/08 06:57:21 itojun Exp $ */
+/* $NetBSD: ld.c,v 1.7 2001/02/04 17:15:37 ad Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -83,15 +83,16 @@
{
char buf[9];
+ if ((sc->sc_flags & LDF_ENABLED) == 0) {
+ printf("%s: disabled\n", sc->sc_dv.dv_xname);
+ return;
+ }
+
/* Initialise and attach the disk structure. */
sc->sc_dk.dk_driver = &lddkdriver;
sc->sc_dk.dk_name = sc->sc_dv.dv_xname;
disk_attach(&sc->sc_dk);
- if ((sc->sc_flags & LDF_ENABLED) == 0) {
- printf("%s: disabled\n", sc->sc_dv.dv_xname);
- return;
- }
if (sc->sc_maxxfer > MAXPHYS)
sc->sc_maxxfer = MAXPHYS;
@@ -114,28 +115,55 @@
}
int
-lddrain(struct ld_softc *sc, int flags)
+ldadjqparam(struct ld_softc *sc, int max)
{
- int s;
+ int s, rv;
+
+ 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);
+}
+
+int
+ldbegindetach(struct ld_softc *sc, int flags)
+{
+ int s, rv;
+
+ if ((sc->sc_flags & LDF_ENABLED) == 0)
+ return (0);
if ((flags & DETACH_FORCE) == 0 && sc->sc_dk.dk_openmask != 0)
return (EBUSY);
s = splbio();
- sc->sc_flags |= LDF_DRAIN;
+ sc->sc_flags |= LDF_DETACH;
+ rv = ldadjqparam(sc, 0);
splx(s);
- return (0);
+
+ return (rv);
}
void
-lddetach(struct ld_softc *sc)
+ldenddetach(struct ld_softc *sc)
{
struct buf *bp;
int s, bmaj, cmaj, mn;
+ if ((sc->sc_flags & LDF_ENABLED) == 0)
+ return;
+
/* Wait for commands queued with the hardware to complete. */
if (sc->sc_queuecnt != 0)
- tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 30 * hz);
+ if (tsleep(&sc->sc_queuecnt, PRIBIO, "lddtch", 30 * hz))
+ printf("%s: not drained\n", sc->sc_dv.dv_xname);
/* Locate the major numbers. */
for (bmaj = 0; bmaj <= nblkdev; bmaj++)
@@ -388,7 +416,7 @@
sc = device_lookup(&ld_cd, DISKUNIT(bp->b_dev));
s = splbio();
- if (sc->sc_queuecnt == sc->sc_maxqueuecnt) {
+ if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) {
BUFQ_INSERT_TAIL(&sc->sc_bufq, bp);
splx(s);
return;
@@ -403,7 +431,7 @@
struct disklabel *lp;
int part, s, rv;
- if ((sc->sc_flags & LDF_DRAIN) != 0) {
+ if ((sc->sc_flags & LDF_DETACH) != 0) {
bp->b_error = EIO;
bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
@@ -488,13 +516,15 @@
rnd_add_uint32(&sc->sc_rnd_source, bp->b_rawblkno);
#endif
biodone(bp);
- if (--sc->sc_queuecnt == 0 && (sc->sc_flags & LDF_DRAIN) != 0)
- wakeup(&sc->sc_queuecnt);
- while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) {
- BUFQ_REMOVE(&sc->sc_bufq, bp);
- if (!ldstart(sc, bp))
- break;
+ if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) {
+ if ((sc->sc_flags & LDF_DRAIN) != 0)
+ wakeup(&sc->sc_queuecnt);
+ while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) {
+ BUFQ_REMOVE(&sc->sc_bufq, bp);
+ if (!ldstart(sc, bp))
+ break;
+ }
}
}
diff -r c7b57076332d -r b209f62a2d8b sys/dev/ldvar.h
--- a/sys/dev/ldvar.h Sun Feb 04 17:05:11 2001 +0000
+++ b/sys/dev/ldvar.h Sun Feb 04 17:15:37 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ldvar.h,v 1.3 2001/01/03 21:01:28 ad Exp $ */
+/* $NetBSD: ldvar.h,v 1.4 2001/02/04 17:15:37 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
int sc_nsectors; /* # sectors per track */
int sc_secsize; /* sector size in bytes */
int sc_maxxfer; /* max xfer size in bytes */
- int sc_maxqueuecnt; /* maximum h/w queue count */
+ int sc_maxqueuecnt; /* maximum h/w queue count */
int (*sc_dump)(struct ld_softc *, void *, int, int);
int (*sc_flush)(struct ld_softc *);
@@ -70,11 +70,13 @@
#define LDF_LKWANTED 0x04 /* lock wanted */
#define LDF_WLABEL 0x08 /* label is writable */
#define LDF_LABELLING 0x10 /* writing label */
-#define LDF_DRAIN 0x20 /* detach pending */
+#define LDF_DRAIN 0x20 /* maxqueuecnt has changed; drain */
+#define LDF_DETACH 0x40 /* detach pending */
+int ldadjqparam(struct ld_softc *, int);
void ldattach(struct ld_softc *);
-void lddetach(struct ld_softc *);
+int ldbegindetach(struct ld_softc *, int);
+void ldenddetach(struct ld_softc *);
void lddone(struct ld_softc *, struct buf *);
-int lddrain(struct ld_softc *, int);
#endif /* !_DEV_LDVAR_H_ */
Home |
Main Index |
Thread Index |
Old Index