diff options
-rw-r--r-- | sys/dev/ata/wd.c | 32 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 37 | ||||
-rw-r--r-- | sys/sys/buf.h | 24 |
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. */ |