summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ata/wd.c32
-rw-r--r--sys/kern/subr_disk.c37
-rw-r--r--sys/sys/buf.h24
3 files changed, 73 insertions, 20 deletions
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c
index ae13f4e3f2a..374580d65ce 100644
--- a/sys/dev/ata/wd.c
+++ b/sys/dev/ata/wd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wd.c,v 1.30 2003/05/20 03:59:35 tedu Exp $ */
+/* $OpenBSD: wd.c,v 1.31 2003/06/25 20:52:57 tedu Exp $ */
/* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */
/*
@@ -134,7 +134,7 @@ struct wd_softc {
/* General disk infos */
struct device sc_dev;
struct disk sc_dk;
- struct buf sc_q;
+ struct bufq_default sc_q;
/* IDE disk soft states */
struct ata_bio sc_wdc_bio; /* current transfer */
struct buf *sc_bp; /* buf being transferred */
@@ -273,6 +273,9 @@ wdattach(parent, self, aux)
char buf[41], c, *p, *q;
WDCDEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
+ wd->sc_q.bufq.bufq_get = bufq_default_get;
+ wd->sc_q.bufq.bufq_add = bufq_default_add;
+
wd->openings = aa_link->aa_openings;
wd->drvp = aa_link->aa_drv_data;
@@ -418,14 +421,12 @@ wddetach(self, flags)
int flags;
{
struct wd_softc *sc = (struct wd_softc *)self;
- struct buf *dp, *bp;
+ struct buf *bp;
int s, bmaj, cmaj, mn;
/* Remove unprocessed buffers from queue */
s = splbio();
- for (dp = &sc->sc_q; (bp = dp->b_actf) != NULL; ) {
- dp->b_actf = bp->b_actf;
-
+ while ((bp = BUFQ_GET(&sc->sc_q)) != NULL) {
bp->b_error = ENXIO;
bp->b_flags |= B_ERROR;
biodone(bp);
@@ -512,7 +513,7 @@ wdstrategy(bp)
goto done;
/* Queue transfer on drive, activate drive and controller if idle. */
s = splbio();
- disksort(&wd->sc_q, bp);
+ BUFQ_ADD(&wd->sc_q, bp);
wdstart(wd);
splx(s);
device_unref(&wd->sc_dev);
@@ -537,18 +538,16 @@ wdstart(arg)
void *arg;
{
struct wd_softc *wd = arg;
- struct buf *dp, *bp=0;
+ struct buf *bp = NULL;
WDCDEBUG_PRINT(("wdstart %s\n", wd->sc_dev.dv_xname),
DEBUG_XFERS);
while (wd->openings > 0) {
/* Is there a buf for us ? */
- dp = &wd->sc_q;
- if ((bp = dp->b_actf) == NULL) /* yes, an assign */
- return;
- dp->b_actf = bp->b_actf;
-
+ if ((bp = BUFQ_GET(&wd->sc_q)) == NULL)
+ return;
+
/*
* Make the command. First lock the device
*/
@@ -1112,11 +1111,8 @@ wdsize(dev)
goto exit;
}
- if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
- size = -1;
- else
- size = wd->sc_dk.dk_label->d_partitions[part].p_size *
- (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+ size = wd->sc_dk.dk_label->d_partitions[part].p_size *
+ (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
size = -1;
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index b26bb3a40b7..cace466e490 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_disk.c,v 1.22 2003/06/02 23:28:06 millert Exp $ */
+/* $OpenBSD: subr_disk.c,v 1.23 2003/06/25 20:52:57 tedu Exp $ */
/* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */
/*
@@ -525,3 +525,38 @@ dk_mountroot()
}
return (*mountrootfn)();
}
+
+void
+bufq_default_add(struct bufq *bq, struct buf *bp)
+{
+ struct bufq_default *bufq = (struct bufq_default *)bq;
+ struct proc *p = bp->b_proc;
+ struct buf *head;
+
+ if (p == NULL || p->p_nice < NZERO)
+ head = &bufq->bufq_head[0];
+ else if (p->p_nice == NZERO)
+ head = &bufq->bufq_head[1];
+ else
+ head = &bufq->bufq_head[2];
+
+ disksort(head, bp);
+}
+
+struct buf *
+bufq_default_get(struct bufq *bq)
+{
+ struct bufq_default *bufq = (struct bufq_default *)bq;
+ struct buf *bp, *head;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ head = &bufq->bufq_head[i];
+ if ((bp = head->b_actf))
+ break;
+ }
+ if (bp == NULL)
+ return (NULL);
+ head->b_actf = bp->b_actf;
+ return (bp);
+}
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 68fcc52b40c..13030886c85 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: buf.h,v 1.43 2003/06/02 23:28:20 millert Exp $ */
+/* $OpenBSD: buf.h,v 1.44 2003/06/25 20:52:57 tedu Exp $ */
/* $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */
/*
@@ -101,6 +101,28 @@ struct buf {
};
/*
+ * bufq
+ * flexible buffer queue routines
+ */
+struct bufq {
+ void (*bufq_add)(struct bufq*, struct buf *);
+ struct buf *(*bufq_get)(struct bufq*);
+};
+
+struct bufq_default {
+ struct bufq bufq;
+ struct buf bufq_head[3];
+};
+
+#define BUFQ_ADD(_bufq, _bp) \
+ ((struct bufq *)_bufq)->bufq_add((struct bufq *)_bufq, _bp)
+#define BUFQ_GET(_bufq) \
+ ((struct bufq *)_bufq)->bufq_get((struct bufq *)_bufq)
+
+void bufq_default_add(struct bufq *, struct buf *);
+struct buf *bufq_default_get(struct bufq *);
+
+/*
* For portability with historic industry practice, the cylinder number has
* to be maintained in the `b_resid' field.
*/