diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/i2o/ioprbs.c | 71 | ||||
-rw-r--r-- | sys/dev/i2o/ioprbsvar.h | 4 |
2 files changed, 22 insertions, 53 deletions
diff --git a/sys/dev/i2o/ioprbs.c b/sys/dev/i2o/ioprbs.c index f56093f4b1c..08981337c90 100644 --- a/sys/dev/i2o/ioprbs.c +++ b/sys/dev/i2o/ioprbs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioprbs.c,v 1.25 2010/11/20 20:11:19 miod Exp $ */ +/* $OpenBSD: ioprbs.c,v 1.26 2011/04/03 16:53:20 dlg Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -99,8 +99,8 @@ struct scsi_xfer *ioprbs_dequeue(struct ioprbs_softc *); void ioprbs_enqueue(struct ioprbs_softc *, struct scsi_xfer *, int); void ioprbs_enqueue_ccb(struct ioprbs_softc *, struct ioprbs_ccb *); int ioprbs_exec_ccb(struct ioprbs_ccb *); -void ioprbs_free_ccb(struct ioprbs_softc *, struct ioprbs_ccb *); -struct ioprbs_ccb *ioprbs_get_ccb(struct ioprbs_softc *, int); +void ioprbs_free_ccb(void *, void *); +void *ioprbs_get_ccb(void *); void ioprbs_internal_cache_cmd(struct scsi_xfer *); void ioprbs_intr(struct device *, struct iop_msg *, void *); void ioprbs_intr_event(struct device *, struct iop_msg *, void *); @@ -186,6 +186,8 @@ ioprbs_attach(struct device *parent, struct device *self, void *aux) TAILQ_INIT(&sc->sc_free_ccb); TAILQ_INIT(&sc->sc_ccbq); LIST_INIT(&sc->sc_queue); + mtx_init(&sc->sc_ccb_mtx); + scsi_iopool_init(&sc->sc_iopool, sc, iopbrs_get_ccb, iopbrs_free_ccb); /* Initialize the ccbs */ for (i = 0; i < IOPRBS_MAX_CCBS; i++) @@ -398,7 +400,7 @@ ioprbs_scsi_cmd(xs) { struct scsi_link *link = xs->sc_link; struct ioprbs_softc *sc = link->adapter_softc; - struct ioprbs_ccb *ccb; + struct ioprbs_ccb *ccb = xs->io; u_int32_t blockno, blockcnt; struct scsi_rw *rw; struct scsi_rw_big *rwb; @@ -486,18 +488,6 @@ ioprbs_scsi_cmd(xs) } } - ccb = ioprbs_get_ccb(sc, xs->flags); - - /* - * We are out of commands, try again in a little while. - */ - if (ccb == NULL) { - xs->error = XS_NO_CCB; - scsi_done(xs); - splx(s); - return; - } - ccb->ic_blockno = blockno; ccb->ic_blockcnt = blockcnt; ccb->ic_xs = xs; @@ -575,7 +565,6 @@ ioprbs_intr(struct device *dv, struct iop_msg *im, void *reply) iop_msg_unmap(iop, im); iop_msg_free(iop, im); scsi_done(xs); - ioprbs_free_ccb(sc, ccb); } void @@ -757,55 +746,33 @@ ioprbs_internal_cache_cmd(xs) xs->error = XS_NOERROR; } -struct ioprbs_ccb * -ioprbs_get_ccb(sc, flags) - struct ioprbs_softc *sc; - int flags; +void * +ioprbs_get_ccb(void *cookie) { + struct iopbrs_softc *sc = cookie; struct ioprbs_ccb *ccb; - int s; - - DPRINTF(("ioprbs_get_ccb(%p, 0x%x) ", sc, flags)); - - s = splbio(); - for (;;) { - ccb = TAILQ_FIRST(&sc->sc_free_ccb); - if (ccb != NULL) - break; - if (flags & SCSI_NOSLEEP) - goto bail_out; - tsleep(&sc->sc_free_ccb, PRIBIO, "ioprbs_ccb", 0); - } - - TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ic_chain); + mtx_enter(&sc->sc_ccb_mtx); + ccb = TAILQ_FIRST(&sc->sc_free_ccb); + if (ccb) + TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ic_chain); + mtx_leave(&sc->sc_ccb_mtx); /* initialise the command */ ccb->ic_flags = 0; - bail_out: - splx(s); return (ccb); } void -ioprbs_free_ccb(sc, ccb) - struct ioprbs_softc *sc; - struct ioprbs_ccb *ccb; +ioprbs_free_ccb(void *cookie, void *io) { - int s; - - DPRINTF(("ioprbs_free_ccb(%p, %p) ", sc, ccb)); - - s = splbio(); + struct iopbrs_softc *sc = cookie; + struct ioprbs_ccb *ccb = io; + mtx_enter(&sc->sc_ccb_mtx); TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ic_chain); - - /* If the free list was empty, wake up potential waiters. */ - if (TAILQ_NEXT(ccb, ic_chain) == NULL) - wakeup(&sc->sc_free_ccb); - - splx(s); + mtx_leave(&sc->sc_ccb_mtx); } void diff --git a/sys/dev/i2o/ioprbsvar.h b/sys/dev/i2o/ioprbsvar.h index c44447ddebd..e98eba5a530 100644 --- a/sys/dev/i2o/ioprbsvar.h +++ b/sys/dev/i2o/ioprbsvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ioprbsvar.h,v 1.3 2007/10/17 15:07:37 deraadt Exp $ */ +/* $OpenBSD: ioprbsvar.h,v 1.4 2011/04/03 16:53:20 dlg Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -73,6 +73,8 @@ struct ioprbs_softc { /* commands which have been returned by the controller */ LIST_HEAD(, scsi_xfer) sc_queue; struct scsi_xfer *sc_queuelast; + struct scsi_iopool sc_iopool; + struct mutex sc_ccb_mtx; }; #define IOPRBS_CLAIMED 0x01 |