diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ata/wd.c | 14 | ||||
-rw-r--r-- | sys/kern/kern_bufq.c | 297 | ||||
-rw-r--r-- | sys/scsi/cd.c | 22 | ||||
-rw-r--r-- | sys/scsi/sd.c | 18 | ||||
-rw-r--r-- | sys/scsi/sdvar.h | 4 | ||||
-rw-r--r-- | sys/scsi/st.c | 22 | ||||
-rw-r--r-- | sys/sys/buf.h | 51 |
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 |