summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/wd.c14
-rw-r--r--sys/kern/kern_bufq.c297
-rw-r--r--sys/scsi/cd.c22
-rw-r--r--sys/scsi/sd.c18
-rw-r--r--sys/scsi/sdvar.h4
-rw-r--r--sys/scsi/st.c22
-rw-r--r--sys/sys/buf.h51
7 files changed, 261 insertions, 167 deletions
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c
index 40b406ae01f..89375d47fd8 100644
--- a/sys/dev/ata/wd.c
+++ b/sys/dev/ata/wd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wd.c,v 1.90 2010/08/31 17:00:32 deraadt Exp $ */
+/* $OpenBSD: wd.c,v 1.91 2010/09/01 01:38:12 dlg Exp $ */
/* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */
/*
@@ -116,7 +116,7 @@ struct wd_softc {
/* General disk infos */
struct device sc_dev;
struct disk sc_dk;
- struct bufq *sc_bufq;
+ struct bufq sc_bufq;
/* IDE disk soft states */
struct ata_bio sc_wdc_bio; /* current transfer */
@@ -361,7 +361,7 @@ wdattach(struct device *parent, struct device *self, void *aux)
* Initialize disk structures.
*/
wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
- wd->sc_bufq = bufq_init(BUFQ_DEFAULT);
+ bufq_init(&wd->sc_bufq, BUFQ_DEFAULT);
wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
if (wd->sc_sdhook == NULL)
printf("%s: WARNING: unable to establish shutdown hook\n",
@@ -416,7 +416,7 @@ wddetach(struct device *self, int flags)
/* Remove unprocessed buffers from queue */
s = splbio();
- while ((bp = BUFQ_DEQUEUE(sc->sc_bufq)) != NULL) {
+ while ((bp = bufq_dequeue(&sc->sc_bufq)) != NULL) {
bp->b_error = ENXIO;
bp->b_flags |= B_ERROR;
biodone(bp);
@@ -438,7 +438,7 @@ wddetach(struct device *self, int flags)
shutdownhook_disestablish(sc->sc_sdhook);
/* Detach disk. */
- bufq_destroy(sc->sc_bufq);
+ bufq_destroy(&sc->sc_bufq);
disk_detach(&sc->sc_dk);
return (0);
@@ -489,7 +489,7 @@ wdstrategy(struct buf *bp)
(wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
goto done;
/* Queue transfer on drive, activate drive and controller if idle. */
- BUFQ_QUEUE(wd->sc_bufq, bp);
+ bufq_queue(&wd->sc_bufq, bp);
s = splbio();
wdstart(wd);
splx(s);
@@ -521,7 +521,7 @@ wdstart(void *arg)
while (wd->openings > 0) {
/* Is there a buf for us ? */
- if ((bp = BUFQ_DEQUEUE(wd->sc_bufq)) == NULL)
+ if ((bp = bufq_dequeue(&wd->sc_bufq)) == NULL)
return;
/*
* Make the command. First lock the device
diff --git a/sys/kern/kern_bufq.c b/sys/kern/kern_bufq.c
index e59cac2faf5..adff3cc4ada 100644
--- a/sys/kern/kern_bufq.c
+++ b/sys/kern/kern_bufq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_bufq.c,v 1.14 2010/07/19 21:39:15 kettenis Exp $ */
+/* $OpenBSD: kern_bufq.c,v 1.15 2010/09/01 01:38:12 dlg Exp $ */
/*
* Copyright (c) 2010 Thordur I. Bjornsson <thib@openbsd.org>
*
@@ -30,45 +30,70 @@ SLIST_HEAD(, bufq) bufqs = SLIST_HEAD_INITIALIZER(&bufq);
struct mutex bufqs_mtx = MUTEX_INITIALIZER(IPL_NONE);
int bufqs_stop;
-struct buf *(*bufq_dequeuev[BUFQ_HOWMANY])(struct bufq *, int) = {
- bufq_disksort_dequeue,
- bufq_fifo_dequeue
+struct bufq_impl {
+ void *(*impl_create)(void);
+ void (*impl_destroy)(void *);
+
+ void (*impl_queue)(void *, struct buf *);
+ struct buf *(*impl_dequeue)(void *);
+ void (*impl_requeue)(void *, struct buf *);
+ int (*impl_peek)(void *);
};
-void (*bufq_queuev[BUFQ_HOWMANY])(struct bufq *, struct buf *) = {
+
+void *bufq_disksort_create(void);
+void bufq_disksort_destroy(void *);
+void bufq_disksort_queue(void *, struct buf *);
+struct buf *bufq_disksort_dequeue(void *);
+void bufq_disksort_requeue(void *, struct buf *);
+int bufq_disksort_peek(void *);
+
+struct bufq_impl bufq_impl_disksort = {
+ bufq_disksort_create,
+ bufq_disksort_destroy,
bufq_disksort_queue,
- bufq_fifo_queue
-};
-void (*bufq_requeuev[BUFQ_HOWMANY])(struct bufq *, struct buf *) = {
+ bufq_disksort_dequeue,
bufq_disksort_requeue,
- bufq_fifo_requeue
+ bufq_disksort_peek
+};
+
+void *bufq_fifo_create(void);
+void bufq_fifo_destroy(void *);
+void bufq_fifo_queue(void *, struct buf *);
+struct buf *bufq_fifo_dequeue(void *);
+void bufq_fifo_requeue(void *, struct buf *);
+int bufq_fifo_peek(void *);
+
+struct bufq_impl bufq_impl_fifo = {
+ bufq_fifo_create,
+ bufq_fifo_destroy,
+ bufq_fifo_queue,
+ bufq_fifo_dequeue,
+ bufq_fifo_requeue,
+ bufq_fifo_peek
};
+struct bufq_impl *bufq_impls[BUFQ_HOWMANY] = {
+ &bufq_impl_disksort,
+ &bufq_impl_fifo
+};
-struct bufq *
-bufq_init(int type)
+int
+bufq_init(struct bufq *bq, int type)
{
- struct bufq *bq;
- int error;
-
- bq = malloc(sizeof(*bq), M_DEVBUF, M_NOWAIT|M_ZERO);
- KASSERT(bq != NULL);
+ if (type > BUFQ_HOWMANY)
+ panic("bufq_init: type %i unknown", type);
mtx_init(&bq->bufq_mtx, IPL_BIO);
bq->bufq_type = type;
-
- switch (type) {
- case BUFQ_DISKSORT:
- error = bufq_disksort_init(bq);
- break;
- case BUFQ_FIFO:
- error = bufq_fifo_init(bq);
- break;
- default:
- panic("bufq_init: type %i unknown", type);
- break;
- };
-
- KASSERT(error == 0);
+ bq->bufq_impl = bufq_impls[type];
+ bq->bufq_data = bq->bufq_impl->impl_create();
+ if (bq->bufq_data == NULL) {
+ /*
+ * we should actually return failure so disks attaching after
+ * boot in low memory situations dont panic the system.
+ */
+ panic("bufq init fail");
+ }
mtx_enter(&bufqs_mtx);
while (bufqs_stop) {
@@ -77,7 +102,48 @@ bufq_init(int type)
SLIST_INSERT_HEAD(&bufqs, bq, bufq_entries);
mtx_leave(&bufqs_mtx);
- return (bq);
+ return (0);
+}
+
+int
+bufq_switch(struct bufq *bq, int type)
+{
+ void *data;
+ void *odata;
+ int otype;
+ struct buf *bp;
+ int ret;
+
+ mtx_enter(&bq->bufq_mtx);
+ ret = (bq->bufq_type == type);
+ mtx_leave(&bq->bufq_mtx);
+ if (ret)
+ return (0);
+
+ data = bufq_impls[type]->impl_create();
+ if (data == NULL)
+ return (ENOMEM);
+
+ mtx_enter(&bq->bufq_mtx);
+ if (bq->bufq_type != type) { /* might have changed during create */
+ odata = bq->bufq_data;
+ otype = bq->bufq_type;
+
+ while ((bp = bufq_impls[otype]->impl_dequeue(odata)) != NULL)
+ bufq_impls[type]->impl_queue(data, bp);
+
+ bq->bufq_data = data;
+ bq->bufq_type = type;
+ bq->bufq_impl = bufq_impls[type];
+ } else {
+ otype = type;
+ odata = data;
+ }
+ mtx_leave(&bq->bufq_mtx);
+
+ bufq_impls[otype]->impl_destroy(odata);
+
+ return (0);
}
void
@@ -85,8 +151,8 @@ bufq_destroy(struct bufq *bq)
{
bufq_drain(bq);
- if (bq->bufq_data != NULL)
- free(bq->bufq_data, M_DEVBUF);
+ bq->bufq_impl->impl_destroy(bq->bufq_data);
+ bq->bufq_data = NULL;
mtx_enter(&bufqs_mtx);
while (bufqs_stop) {
@@ -94,10 +160,9 @@ bufq_destroy(struct bufq *bq)
}
SLIST_REMOVE(&bufqs, bq, bufq, bufq_entries);
mtx_leave(&bufqs_mtx);
-
- free(bq, M_DEVBUF);
}
+
void
bufq_queue(struct bufq *bq, struct buf *bp)
{
@@ -105,16 +170,43 @@ bufq_queue(struct bufq *bq, struct buf *bp)
while (bq->bufq_stop) {
msleep(&bq->bufq_stop, &bq->bufq_mtx, PRIBIO, "bqqueue", 0);
}
- bufq_queuev[bq->bufq_type](bq, bp);
+
+ bp->b_bq = bq;
+ bq->bufq_outstanding++;
+ bq->bufq_impl->impl_queue(bq->bufq_data, bp);
+ mtx_leave(&bq->bufq_mtx);
+}
+
+struct buf *
+bufq_dequeue(struct bufq *bq)
+{
+ struct buf *bp;
+
+ mtx_enter(&bq->bufq_mtx);
+ bp = bq->bufq_impl->impl_dequeue(bq->bufq_data);
mtx_leave(&bq->bufq_mtx);
+
+ return (bp);
}
void
bufq_requeue(struct bufq *bq, struct buf *bp)
{
mtx_enter(&bq->bufq_mtx);
- bufq_requeuev[bq->bufq_type](bq, bp);
+ bq->bufq_impl->impl_requeue(bq->bufq_data, bp);
+ mtx_leave(&bq->bufq_mtx);
+}
+
+int
+bufq_peek(struct bufq *bq)
+{
+ int rv;
+
+ mtx_enter(&bq->bufq_mtx);
+ rv = bq->bufq_impl->impl_peek(bq->bufq_data);
mtx_leave(&bq->bufq_mtx);
+
+ return (rv);
}
void
@@ -123,7 +215,7 @@ bufq_drain(struct bufq *bq)
struct buf *bp;
int s;
- while ((bp = BUFQ_DEQUEUE(bq)) != NULL) {
+ while ((bp = bufq_dequeue(bq)) != NULL) {
bp->b_error = ENXIO;
bp->b_flags |= B_ERROR;
s = splbio();
@@ -138,7 +230,7 @@ bufq_done(struct bufq *bq, struct buf *bp)
mtx_enter(&bq->bufq_mtx);
bq->bufq_outstanding--;
KASSERT(bq->bufq_outstanding >= 0);
- if (bq->bufq_outstanding == 0)
+ if (bq->bufq_outstanding == 0 /* XXX and quiesced */)
wakeup(&bq->bufq_outstanding);
mtx_leave(&bq->bufq_mtx);
bp->b_bq = NULL;
@@ -152,7 +244,7 @@ bufq_quiesce(void)
mtx_enter(&bufqs_mtx);
bufqs_stop = 1;
mtx_leave(&bufqs_mtx);
- SLIST_FOREACH(bq, &bufqs, bufq_entries) {
+ SLIST_FOREACH(bq, &bufqs, bufq_entries) { /* XXX */
mtx_enter(&bq->bufq_mtx);
bq->bufq_stop = 1;
while (bq->bufq_outstanding) {
@@ -180,24 +272,47 @@ bufq_restart(void)
mtx_leave(&bufqs_mtx);
}
+/*
+ * disksort implementation.
+ */
+
+void *
+bufq_disksort_create(void)
+{
+ return (malloc(sizeof(struct buf), M_DEVBUF, M_NOWAIT | M_ZERO));
+}
+
void
-bufq_disksort_queue(struct bufq *bq, struct buf *bp)
+bufq_disksort_destroy(void *data)
{
- struct buf *bufq;
+ free(data, M_DEVBUF);
+}
- bufq = (struct buf *)bq->bufq_data;
+void
+bufq_disksort_queue(void *data, struct buf *bp)
+{
+ disksort((struct buf *)data, bp);
+}
- bq->bufq_outstanding++;
- bp->b_bq = bq;
- disksort(bufq, bp);
+struct buf *
+bufq_disksort_dequeue(void *data)
+{
+ struct buf *bufq = data;
+ struct buf *bp;
+
+ bp = bufq->b_actf;
+ if (bp != NULL)
+ bufq->b_actf = bp->b_actf;
+ if (bufq->b_actf == NULL)
+ bufq->b_actb = &bufq->b_actf;
+
+ return (bp);
}
void
-bufq_disksort_requeue(struct bufq *bq, struct buf *bp)
+bufq_disksort_requeue(void *data, struct buf *bp)
{
- struct buf *bufq;
-
- bufq = (struct buf *)bq->bufq_data;
+ struct buf *bufq = data;
bp->b_actf = bufq->b_actf;
bufq->b_actf = bp;
@@ -205,83 +320,71 @@ bufq_disksort_requeue(struct bufq *bq, struct buf *bp)
bufq->b_actb = &bp->b_actf;
}
-struct buf *
-bufq_disksort_dequeue(struct bufq *bq, int peeking)
+int
+bufq_disksort_peek(void *data)
{
- struct buf *bufq, *bp;
-
- mtx_enter(&bq->bufq_mtx);
- bufq = (struct buf *)bq->bufq_data;
- bp = bufq->b_actf;
- if (!peeking) {
- if (bp != NULL)
- bufq->b_actf = bp->b_actf;
- if (bufq->b_actf == NULL)
- bufq->b_actb = &bufq->b_actf;
- }
- mtx_leave(&bq->bufq_mtx);
+ struct buf *bufq = data;
- return (bp);
+ return (bufq->b_actf != NULL);
}
-int
-bufq_disksort_init(struct bufq *bq)
+/*
+ * fifo implementation
+ */
+
+void *
+bufq_fifo_create(void)
{
- int error = 0;
+ struct bufq_fifo_head *head;
- bq->bufq_data = malloc(sizeof(struct buf), M_DEVBUF,
- M_NOWAIT|M_ZERO);
+ head = malloc(sizeof(*head), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (head == NULL)
+ return (NULL);
- if (bq->bufq_data == NULL)
- error = ENOMEM;
+ SIMPLEQ_INIT(head);
- return (error);
+ return (head);
}
void
-bufq_fifo_queue(struct bufq *bq, struct buf *bp)
+bufq_fifo_destroy(void *data)
{
- struct bufq_fifo_head *head = bq->bufq_data;
-
- bq->bufq_outstanding++;
- bp->b_bq = bq;
- SIMPLEQ_INSERT_TAIL(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
+ free(data, M_DEVBUF);
}
void
-bufq_fifo_requeue(struct bufq *bq, struct buf *bp)
+bufq_fifo_queue(void *data, struct buf *bp)
{
- struct bufq_fifo_head *head = bq->bufq_data;
+ struct bufq_fifo_head *head = data;
- SIMPLEQ_INSERT_HEAD(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
+ SIMPLEQ_INSERT_TAIL(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
}
struct buf *
-bufq_fifo_dequeue(struct bufq *bq, int peeking)
+bufq_fifo_dequeue(void *data)
{
- struct bufq_fifo_head *head = bq->bufq_data;
- struct buf *bp;
+ struct bufq_fifo_head *head = data;
+ struct buf *bp;
- mtx_enter(&bq->bufq_mtx);
bp = SIMPLEQ_FIRST(head);
- if (bp != NULL && !peeking)
+ if (bp != NULL)
SIMPLEQ_REMOVE_HEAD(head, b_bufq.bufq_data_fifo.bqf_entries);
- mtx_leave(&bq->bufq_mtx);
return (bp);
}
-int
-bufq_fifo_init(struct bufq *bq)
+void
+bufq_fifo_requeue(void *data, struct buf *bp)
{
- struct bufq_fifo_head *head;
+ struct bufq_fifo_head *head = data;
- head = malloc(sizeof(*head), M_DEVBUF, M_NOWAIT);
- if (head == NULL)
- return (ENOMEM);
+ SIMPLEQ_INSERT_HEAD(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
+}
- SIMPLEQ_INIT(head);
- bq->bufq_data = head;
+int
+bufq_fifo_peek(void *data)
+{
+ struct bufq_fifo_head *head = data;
- return (0);
+ return (SIMPLEQ_FIRST(head) != NULL);
}
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index adbc211842e..e5fa0b3b650 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cd.c,v 1.184 2010/08/31 16:41:24 deraadt Exp $ */
+/* $OpenBSD: cd.c,v 1.185 2010/09/01 01:38:12 dlg Exp $ */
/* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */
/*
@@ -111,7 +111,7 @@ struct cd_softc {
u_int32_t blksize;
daddr64_t disksize; /* total number sectors */
} sc_params;
- struct bufq *sc_bufq;
+ struct bufq sc_bufq;
struct scsi_xshandler sc_xsh;
struct timeout sc_timeout;
void *sc_cdpwrhook; /* our power hook */
@@ -219,7 +219,7 @@ cdattach(struct device *parent, struct device *self, void *aux)
* Initialize disk structures.
*/
sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
- sc->sc_bufq = bufq_init(BUFQ_DEFAULT);
+ bufq_init(&sc->sc_bufq, BUFQ_DEFAULT);
/*
* Note if this device is ancient. This is used in cdminphys().
@@ -263,7 +263,7 @@ cdactivate(struct device *self, int act)
break;
case DVACT_DEACTIVATE:
sc->sc_flags |= CDF_DYING;
- bufq_drain(sc->sc_bufq);
+ bufq_drain(&sc->sc_bufq);
break;
}
return (rv);
@@ -294,7 +294,7 @@ cddetach(struct device *self, int flags)
struct cd_softc *sc = (struct cd_softc *)self;
int bmaj, cmaj, mn;
- bufq_drain(sc->sc_bufq);
+ bufq_drain(&sc->sc_bufq);
/* Locate the lowest minor number to be detached. */
mn = DISKMINOR(self->dv_unit, 0);
@@ -311,7 +311,7 @@ cddetach(struct device *self, int flags)
powerhook_disestablish(sc->sc_cdpwrhook);
/* Detach disk. */
- bufq_destroy(sc->sc_bufq);
+ bufq_destroy(&sc->sc_bufq);
disk_detach(&sc->sc_dk);
return (0);
@@ -556,7 +556,7 @@ cdstrategy(struct buf *bp)
goto done;
/* Place it in the queue of disk activities for this disk. */
- BUFQ_QUEUE(sc->sc_bufq, bp);
+ bufq_queue(&sc->sc_bufq, bp);
/*
* Tell the device to get going on the transfer if it's
@@ -622,12 +622,12 @@ cdstart(struct scsi_xfer *xs)
* re-opened
*/
if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
- bufq_drain(sc->sc_bufq);
+ bufq_drain(&sc->sc_bufq);
scsi_xs_put(xs);
return;
}
- bp = BUFQ_DEQUEUE(sc->sc_bufq);
+ bp = bufq_dequeue(&sc->sc_bufq);
if (bp == NULL) {
scsi_xs_put(xs);
return;
@@ -691,7 +691,7 @@ cdstart(struct scsi_xfer *xs)
if (ISSET(sc->sc_flags, CDF_WAITING))
CLR(sc->sc_flags, CDF_WAITING);
- else if (BUFQ_PEEK(sc->sc_bufq))
+ else if (bufq_peek(&sc->sc_bufq))
scsi_xsh_add(&sc->sc_xsh);
}
@@ -712,7 +712,7 @@ cd_buf_done(struct scsi_xfer *xs)
/* The adapter is busy, requeue the buf and try it later. */
disk_unbusy(&sc->sc_dk, bp->b_bcount - xs->resid,
bp->b_flags & B_READ);
- BUFQ_REQUEUE(sc->sc_bufq, bp);
+ bufq_requeue(&sc->sc_bufq, bp);
scsi_xs_put(xs);
SET(sc->sc_flags, CDF_WAITING);
timeout_add(&sc->sc_timeout, 1);
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 8ca02b80fd4..fe2815bebce 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.207 2010/08/31 16:34:38 deraadt Exp $ */
+/* $OpenBSD: sd.c,v 1.208 2010/09/01 01:38:12 dlg Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -172,7 +172,7 @@ sdattach(struct device *parent, struct device *self, void *aux)
* Initialize disk structures.
*/
sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
- sc->sc_bufq = bufq_init(BUFQ_DEFAULT);
+ bufq_init(&sc->sc_bufq, BUFQ_DEFAULT);
if ((sc_link->flags & SDEV_ATAPI) && (sc_link->flags & SDEV_REMOVABLE))
sc_link->quirks |= SDEV_NOSYNCCACHE;
@@ -302,7 +302,7 @@ sddetach(struct device *self, int flags)
struct sd_softc *sc = (struct sd_softc *)self;
int bmaj, cmaj, mn;
- bufq_drain(sc->sc_bufq);
+ bufq_drain(&sc->sc_bufq);
/* Locate the lowest minor number to be detached. */
mn = DISKMINOR(self->dv_unit, 0);
@@ -319,7 +319,7 @@ sddetach(struct device *self, int flags)
shutdownhook_disestablish(sc->sc_sdhook);
/* Detach disk. */
- bufq_destroy(sc->sc_bufq);
+ bufq_destroy(&sc->sc_bufq);
disk_detach(&sc->sc_dk);
return (0);
@@ -574,7 +574,7 @@ sdstrategy(struct buf *bp)
goto done;
/* Place it in the queue of disk activities for this disk. */
- BUFQ_QUEUE(sc->sc_bufq, bp);
+ bufq_queue(&sc->sc_bufq, bp);
/*
* Tell the device to get going on the transfer if it's
@@ -676,12 +676,12 @@ sdstart(struct scsi_xfer *xs)
return;
}
if ((link->flags & SDEV_MEDIA_LOADED) == 0) {
- bufq_drain(sc->sc_bufq);
+ bufq_drain(&sc->sc_bufq);
scsi_xs_put(xs);
return;
}
- bp = BUFQ_DEQUEUE(sc->sc_bufq);
+ bp = bufq_dequeue(&sc->sc_bufq);
if (bp == NULL) {
scsi_xs_put(xs);
return;
@@ -732,7 +732,7 @@ sdstart(struct scsi_xfer *xs)
/* move onto the next io */
if (ISSET(sc->flags, SDF_WAITING))
CLR(sc->flags, SDF_WAITING);
- else if (BUFQ_PEEK(sc->sc_bufq) != NULL)
+ else if (bufq_peek(&sc->sc_bufq) != NULL)
scsi_xsh_add(&sc->sc_xsh);
}
@@ -753,7 +753,7 @@ sd_buf_done(struct scsi_xfer *xs)
/* The adapter is busy, requeue the buf and try it later. */
disk_unbusy(&sc->sc_dk, bp->b_bcount - xs->resid,
bp->b_flags & B_READ);
- BUFQ_REQUEUE(sc->sc_bufq, bp);
+ bufq_requeue(&sc->sc_bufq, bp);
scsi_xs_put(xs);
SET(sc->flags, SDF_WAITING);
timeout_add(&sc->sc_timeout, 1);
diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h
index d5debe6a498..0a158b4c382 100644
--- a/sys/scsi/sdvar.h
+++ b/sys/scsi/sdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdvar.h,v 1.31 2010/06/02 13:32:13 dlg Exp $ */
+/* $OpenBSD: sdvar.h,v 1.32 2010/09/01 01:38:12 dlg Exp $ */
/* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */
/*-
@@ -51,7 +51,7 @@
struct sd_softc {
struct device sc_dev;
struct disk sc_dk;
- struct bufq *sc_bufq;
+ struct bufq sc_bufq;
int flags;
#define SDF_LOCKED 0x01
diff --git a/sys/scsi/st.c b/sys/scsi/st.c
index 5ce3c057a0e..56556e69fb9 100644
--- a/sys/scsi/st.c
+++ b/sys/scsi/st.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: st.c,v 1.107 2010/08/30 02:47:56 matthew Exp $ */
+/* $OpenBSD: st.c,v 1.108 2010/09/01 01:38:12 dlg Exp $ */
/* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */
/*
@@ -215,7 +215,7 @@ struct st_softc {
#define BLKSIZE_SET_BY_USER 0x04
#define BLKSIZE_SET_BY_QUIRK 0x08
- struct bufq *sc_bufq;
+ struct bufq sc_bufq;
struct timeout sc_timeout;
struct scsi_xshandler sc_xsh;
};
@@ -331,7 +331,7 @@ stattach(struct device *parent, struct device *self, void *aux)
&st->sc_xsh);
/* Set up the buf queue for this device. */
- st->sc_bufq = bufq_init(BUFQ_FIFO);
+ bufq_init(&st->sc_bufq, BUFQ_FIFO);
/* Start up with media position unknown. */
st->media_fileno = -1;
@@ -357,7 +357,7 @@ stactivate(struct device *self, int act)
case DVACT_DEACTIVATE:
st->flags |= ST_DYING;
- bufq_drain(st->sc_bufq);
+ bufq_drain(&st->sc_bufq);
break;
}
@@ -370,7 +370,7 @@ stdetach(struct device *self, int flags)
struct st_softc *st = (struct st_softc *)self;
int bmaj, cmaj, mn;
- bufq_drain(st->sc_bufq);
+ bufq_drain(&st->sc_bufq);
/* Locate the lowest minor number to be detached. */
mn = STUNIT(self->dv_unit);
@@ -390,7 +390,7 @@ stdetach(struct device *self, int flags)
vdevgone(cmaj, mn, mn + 3, VCHR);
}
- bufq_destroy(st->sc_bufq);
+ bufq_destroy(&st->sc_bufq);
return (0);
}
@@ -877,7 +877,7 @@ ststrategy(struct buf *bp)
* at the end (a bit silly because we only have on user..
* (but it could fork()))
*/
- BUFQ_QUEUE(st->sc_bufq, bp);
+ bufq_queue(&st->sc_bufq, bp);
/*
* Tell the device to get going on the transfer if it's
@@ -922,13 +922,13 @@ ststart(struct scsi_xfer *xs)
!(sc_link->flags & SDEV_MEDIA_LOADED)) {
/* make sure that one implies the other.. */
sc_link->flags &= ~SDEV_MEDIA_LOADED;
- bufq_drain(st->sc_bufq);
+ bufq_drain(&st->sc_bufq);
scsi_xs_put(xs);
return;
}
for (;;) {
- bp = BUFQ_DEQUEUE(st->sc_bufq);
+ bp = bufq_dequeue(&st->sc_bufq);
if (bp == NULL) {
scsi_xs_put(xs);
return;
@@ -1041,7 +1041,7 @@ ststart(struct scsi_xfer *xs)
*/
if (ISSET(st->flags, ST_WAITING))
CLR(st->flags, ST_WAITING);
- else if (BUFQ_PEEK(st->sc_bufq))
+ else if (bufq_peek(&st->sc_bufq))
scsi_xsh_add(&st->sc_xsh);
}
@@ -1060,7 +1060,7 @@ st_buf_done(struct scsi_xfer *xs)
case XS_NO_CCB:
/* The adapter is busy, requeue the buf and try it later. */
- BUFQ_REQUEUE(st->sc_bufq, bp);
+ bufq_requeue(&st->sc_bufq, bp);
scsi_xs_put(xs);
SET(st->flags, ST_WAITING); /* dont let ststart xsh_add */
timeout_add(&st->sc_timeout, 1);
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 3b047300dd5..7ff8938bb9b 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: buf.h,v 1.70 2010/06/30 02:26:58 matthew Exp $ */
+/* $OpenBSD: buf.h,v 1.71 2010/09/01 01:38:12 dlg Exp $ */
/* $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */
/*
@@ -67,6 +67,8 @@ LIST_HEAD(workhead, worklist);
#define BUFQ_DEFAULT BUFQ_DISKSORT
#define BUFQ_HOWMANY 2
+struct bufq_impl;
+
struct bufq {
SLIST_ENTRY(bufq) bufq_entries;
struct mutex bufq_mtx;
@@ -74,52 +76,41 @@ struct bufq {
u_int bufq_outstanding;
int bufq_stop;
int bufq_type;
+ struct bufq_impl *bufq_impl;
};
-struct buf *bufq_disksort_dequeue(struct bufq *, int);
-void bufq_disksort_queue(struct bufq *, struct buf *);
-void bufq_disksort_requeue(struct bufq *, struct buf *);
-int bufq_disksort_init(struct bufq *);
+int bufq_init(struct bufq *, int);
+int bufq_switch(struct bufq *, int);
+void bufq_destroy(struct bufq *);
+
+void bufq_queue(struct bufq *, struct buf *);
+struct buf *bufq_dequeue(struct bufq *);
+void bufq_requeue(struct bufq *, struct buf *);
+int bufq_peek(struct bufq *);
+void bufq_drain(struct bufq *);
+
+void bufq_done(struct bufq *, struct buf *);
+void bufq_quiesce(void);
+void bufq_restart(void);
+
+/* disksort */
struct bufq_disksort {
struct buf *bqd_actf;
struct buf **bqd_actb;
};
-struct buf *bufq_fifo_dequeue(struct bufq *, int);
-void bufq_fifo_queue(struct bufq *, struct buf *);
-void bufq_fifo_requeue(struct bufq *, struct buf *);
-int bufq_fifo_init(struct bufq *);
+/* fifo */
SIMPLEQ_HEAD(bufq_fifo_head, buf);
struct bufq_fifo {
SIMPLEQ_ENTRY(buf) bqf_entries;
};
+/* bufq link in struct buf */
union bufq_data {
struct bufq_disksort bufq_data_disksort;
struct bufq_fifo bufq_data_fifo;
};
-extern struct buf *(*bufq_dequeuev[BUFQ_HOWMANY])(struct bufq *, int);
-extern void (*bufq_queuev[BUFQ_HOWMANY])(struct bufq *, struct buf *);
-extern void (*bufq_requeuev[BUFQ_HOWMANY])(struct bufq *, struct buf *);
-
-#define BUFQ_QUEUE(_bufq, _bp) bufq_queue(_bufq, _bp)
-#define BUFQ_REQUEUE(_bufq, _bp) bufq_requeue(_bufq, _bp)
-#define BUFQ_DEQUEUE(_bufq) \
- bufq_dequeuev[(_bufq)->bufq_type](_bufq, 0)
-#define BUFQ_PEEK(_bufq) \
- bufq_dequeuev[(_bufq)->bufq_type](_bufq, 1)
-
-struct bufq *bufq_init(int);
-void bufq_queue(struct bufq *, struct buf *);
-void bufq_requeue(struct bufq *, struct buf *);
-void bufq_destroy(struct bufq *);
-void bufq_drain(struct bufq *);
-void bufq_done(struct bufq *, struct buf *);
-void bufq_quiesce(void);
-void bufq_restart(void);
-
-
/*
* These are currently used only by the soft dependency code, hence
* are stored once in a global variable. If other subsystems wanted