this diff is largely a mechanical change.

firstly, it makes struct bufq a member of the softc for devices
that use it, rather than it being a pointer to something that needs
to be allocated at attach. since all these devices need a bufq to
operate, it makes sense to have it allocated as part of the softc
and get bufq_init to just initialise all its fields. it also gets
rid of the possibility that you wont be able to allocate teh bufq
struct during attach, which is something you dont want to happen.

secondly, it consistently implements a split between wrapper functions
and the per discipline implementation of the bufq handlers. it
consistently does the locking in the wrappers rather than doing
half in the wrappers and the other half in the implementations.

it also consistently handles the outstanding bufq bq pointer in the
wrappers.

this hides most of the implementation inside kern_bufq.c. the only
stuff left in buf.h is for the bits each implementation needs to
put bufs on their queues.

ive tested this extensively on sd(4) and thib has tested this on
wd(4). we'd like some wider exposure, especially over suspends and
resumes on a variety of machines. i have tried to preserve the
locking semantics, but testing would be lovely.

ok?

dlg

Index: dev/ata/wd.c
===================================================================
RCS file: /cvs/src/sys/dev/ata/wd.c,v
retrieving revision 1.85
diff -u -p -r1.85 wd.c
--- dev/ata/wd.c        28 Jun 2010 08:35:46 -0000      1.85
+++ dev/ata/wd.c        25 Aug 2010 12:05:33 -0000
@@ -121,7 +121,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 */
@@ -369,7 +369,7 @@ wdattach(struct device *parent, struct d
         */
        wd->sc_dk.dk_driver = &wddkdriver;
        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",
@@ -413,7 +413,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);
@@ -435,7 +435,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);
@@ -486,7 +486,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);
@@ -518,7 +518,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
Index: kern/kern_bufq.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_bufq.c,v
retrieving revision 1.14
diff -u -p -r1.14 kern_bufq.c
--- kern/kern_bufq.c    19 Jul 2010 21:39:15 -0000      1.14
+++ kern/kern_bufq.c    25 Aug 2010 12:05:33 -0000
@@ -30,45 +30,70 @@ SLIST_HEAD(, bufq)  bufqs = SLIST_HEAD_IN
 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 *
-bufq_init(int type)
-{
-       struct bufq     *bq;
-       int              error;
+struct bufq_impl *bufq_impls[BUFQ_HOWMANY] = {
+       &bufq_impl_disksort,
+       &bufq_impl_fifo
+};
 
-       bq = malloc(sizeof(*bq), M_DEVBUF, M_NOWAIT|M_ZERO);
-       KASSERT(bq != NULL);
+int
+bufq_init(struct bufq *bq, int type)
+{
+       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 *
        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 *b
        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, s
                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;
+       struct buf      *bufq = data;
 
-       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);
-
-       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);
 }
Index: scsi/cd.c
===================================================================
RCS file: /cvs/src/sys/scsi/cd.c,v
retrieving revision 1.181
diff -u -p -r1.181 cd.c
--- scsi/cd.c   28 Jul 2010 23:47:43 -0000      1.181
+++ scsi/cd.c   25 Aug 2010 12:05:33 -0000
@@ -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 d
         */
        sc->sc_dk.dk_driver = &cddkdriver;
        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().
@@ -255,7 +255,7 @@ cdactivate(struct device *self, int act)
 
        case DVACT_DEACTIVATE:
                sc->sc_flags |= CDF_DYING;
-               bufq_drain(sc->sc_bufq);
+               bufq_drain(&sc->sc_bufq);
                break;
        }
        return (rv);
@@ -268,7 +268,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);
@@ -285,7 +285,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);
@@ -530,7 +530,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
@@ -596,12 +596,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;
@@ -665,7 +665,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);
 }
 
@@ -686,7 +686,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);
Index: scsi/sd.c
===================================================================
RCS file: /cvs/src/sys/scsi/sd.c,v
retrieving revision 1.205
diff -u -p -r1.205 sd.c
--- scsi/sd.c   3 Aug 2010 19:37:17 -0000       1.205
+++ scsi/sd.c   25 Aug 2010 12:05:33 -0000
@@ -175,7 +175,7 @@ sdattach(struct device *parent, struct d
         */
        sc->sc_dk.dk_driver = &sddkdriver;
        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;
@@ -279,7 +279,7 @@ sdactivate(struct device *self, int act)
 
        case DVACT_DEACTIVATE:
                sc->flags |= SDF_DYING;
-               bufq_drain(sc->sc_bufq);
+               bufq_drain(&sc->sc_bufq);
                break;
 
        case DVACT_SUSPEND:
@@ -309,7 +309,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);
@@ -326,7 +326,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);
@@ -581,7 +581,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
@@ -683,12 +683,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;
@@ -739,7 +739,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);
 }
 
@@ -760,7 +760,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);
Index: scsi/sdvar.h
===================================================================
RCS file: /cvs/src/sys/scsi/sdvar.h,v
retrieving revision 1.31
diff -u -p -r1.31 sdvar.h
--- scsi/sdvar.h        2 Jun 2010 13:32:13 -0000       1.31
+++ scsi/sdvar.h        25 Aug 2010 12:05:33 -0000
@@ -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
Index: scsi/st.c
===================================================================
RCS file: /cvs/src/sys/scsi/st.c,v
retrieving revision 1.106
diff -u -p -r1.106 st.c
--- scsi/st.c   22 Jul 2010 05:26:34 -0000      1.106
+++ scsi/st.c   25 Aug 2010 12:05:33 -0000
@@ -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 d
            &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);
Index: sys/buf.h
===================================================================
RCS file: /cvs/src/sys/sys/buf.h,v
retrieving revision 1.70
diff -u -p -r1.70 buf.h
--- sys/buf.h   30 Jun 2010 02:26:58 -0000      1.70
+++ sys/buf.h   25 Aug 2010 12:05:33 -0000
@@ -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,51 +76,40 @@ 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

Reply via email to