diff options
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/adv.c | 94 | ||||
-rw-r--r-- | sys/dev/ic/advlib.h | 4 | ||||
-rw-r--r-- | sys/dev/ic/aic6360.c | 52 | ||||
-rw-r--r-- | sys/dev/ic/aic6360var.h | 5 | ||||
-rw-r--r-- | sys/dev/ic/bha.c | 86 | ||||
-rw-r--r-- | sys/dev/ic/bhavar.h | 5 | ||||
-rw-r--r-- | sys/dev/ic/oosiop.c | 44 | ||||
-rw-r--r-- | sys/dev/ic/oosiopvar.h | 5 | ||||
-rw-r--r-- | sys/dev/ic/uha.c | 91 | ||||
-rw-r--r-- | sys/dev/ic/uhavar.h | 6 |
10 files changed, 160 insertions, 232 deletions
diff --git a/sys/dev/ic/adv.c b/sys/dev/ic/adv.c index ef274934cd0..ae2ef0e0215 100644 --- a/sys/dev/ic/adv.c +++ b/sys/dev/ic/adv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: adv.c,v 1.33 2010/08/07 03:50:01 krw Exp $ */ +/* $OpenBSD: adv.c,v 1.34 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: adv.c,v 1.6 1998/10/28 20:39:45 dante Exp $ */ /* @@ -58,10 +58,10 @@ static int adv_alloc_ccbs(ASC_SOFTC *); static int adv_create_ccbs(ASC_SOFTC *, ADV_CCB *, int); -static void adv_free_ccb(ASC_SOFTC *, ADV_CCB *); +void adv_ccb_free(void *, void *); static void adv_reset_ccb(ADV_CCB *); static int adv_init_ccb(ASC_SOFTC *, ADV_CCB *); -static ADV_CCB *adv_get_ccb(ASC_SOFTC *, int); +void *adv_ccb_alloc(void *); static void adv_queue_ccb(ASC_SOFTC *, ADV_CCB *); static void adv_start_ccbs(ASC_SOFTC *); @@ -178,26 +178,18 @@ adv_create_ccbs(sc, ccbstore, count) /* * A ccb is put onto the free list. */ -static void -adv_free_ccb(sc, ccb) - ASC_SOFTC *sc; - ADV_CCB *ccb; +void +adv_ccb_free(xsc, xccb) + void *xsc, *xccb; { - int s; - - s = splbio(); + ASC_SOFTC *sc = xsc; + ADV_CCB *ccb = xccb; adv_reset_ccb(ccb); - TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); - - /* - * If there were none, wake anybody waiting for one to come free, - * starting with queued entries. - */ - if (TAILQ_NEXT(ccb, chain) == NULL) - wakeup(&sc->sc_free_ccb); - splx(s); + mtx_enter(&sc->sc_ccb_mtx); + TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); + mtx_leave(&sc->sc_ccb_mtx); } @@ -236,43 +228,25 @@ adv_init_ccb(sc, ccb) /* * Get a free ccb - * - * If there are none, see if we can allocate a new one */ -static ADV_CCB * -adv_get_ccb(sc, flags) - ASC_SOFTC *sc; - int flags; +void * +adv_ccb_alloc(xsc) + void *xsc; { - ADV_CCB *ccb = 0; - int s; - - s = splbio(); - - /* - * If we can and have to, sleep waiting for one to come free - * but only if we can't allocate a new one. - */ - for (;;) { - ccb = TAILQ_FIRST(&sc->sc_free_ccb); - if (ccb) { - TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); - break; - } - if ((flags & SCSI_NOSLEEP) != 0) - goto out; - - tsleep(&sc->sc_free_ccb, PRIBIO, "advccb", 0); + ASC_SOFTC *sc = xsc; + ADV_CCB *ccb; + + mtx_enter(&sc->sc_ccb_mtx); + ccb = TAILQ_FIRST(&sc->sc_free_ccb); + if (ccb) { + TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); + ccb->flags |= CCB_ALLOC; } + mtx_leave(&sc->sc_ccb_mtx); - ccb->flags |= CCB_ALLOC; - -out: - splx(s); return (ccb); } - /* * Queue a CCB to be sent to the controller, and send it if possible. */ @@ -506,6 +480,11 @@ adv_attach(sc) sc->sc_dev.dv_xname); } + TAILQ_INIT(&sc->sc_free_ccb); + TAILQ_INIT(&sc->sc_waiting_ccb); + + mtx_init(&sc->sc_ccb_mtx, IPL_BIO); + scsi_iopool_init(&sc->sc_iopool, sc, adv_ccb_alloc, adv_ccb_free); /* * fill in the prototype scsi_link. @@ -514,13 +493,9 @@ adv_attach(sc) sc->sc_link.adapter_target = sc->chip_scsi_id; sc->sc_link.adapter = &adv_switch; sc->sc_link.openings = 4; + sc->sc_link.pool = &sc->sc_iopool; sc->sc_link.adapter_buswidth = 7; - - TAILQ_INIT(&sc->sc_free_ccb); - TAILQ_INIT(&sc->sc_waiting_ccb); - - /* * Allocate the Control Blocks. */ @@ -579,13 +554,7 @@ adv_scsi_cmd(xs) */ flags = xs->flags; - if ((ccb = adv_get_ccb(sc, flags)) == NULL) { - xs->error = XS_NO_CCB; - scsi_done(xs); - splx(s); - return; - } - splx(s); /* done playing with the queue */ + ccb = xs->io; ccb->xs = xs; ccb->timeout = xs->timeout; @@ -643,7 +612,6 @@ adv_scsi_cmd(xs) } xs->error = XS_DRIVER_STUFFUP; - adv_free_ccb(sc, ccb); scsi_done(xs); return; } @@ -914,7 +882,5 @@ adv_narrow_isr_callback(sc, qdonep) break; } - - adv_free_ccb(sc, ccb); scsi_done(xs); } diff --git a/sys/dev/ic/advlib.h b/sys/dev/ic/advlib.h index a04ef71d54f..50f620fa043 100644 --- a/sys/dev/ic/advlib.h +++ b/sys/dev/ic/advlib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: advlib.h,v 1.10 2008/11/26 16:39:31 krw Exp $ */ +/* $OpenBSD: advlib.h,v 1.11 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: advlib.h,v 1.5 1998/10/28 20:39:46 dante Exp $ */ /* @@ -835,6 +835,8 @@ typedef struct asc_softc struct adv_control *sc_control; /* control structures */ TAILQ_HEAD(, adv_ccb) sc_free_ccb, sc_waiting_ccb; struct scsi_link sc_link; /* prototype for devs */ + struct mutex sc_ccb_mtx; + struct scsi_iopool sc_iopool; u_int8_t *overrun_buf; diff --git a/sys/dev/ic/aic6360.c b/sys/dev/ic/aic6360.c index ca796621ee1..1c77a61021e 100644 --- a/sys/dev/ic/aic6360.c +++ b/sys/dev/ic/aic6360.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aic6360.c,v 1.25 2010/06/28 18:31:02 krw Exp $ */ +/* $OpenBSD: aic6360.c,v 1.26 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: aic6360.c,v 1.52 1996/12/10 21:27:51 thorpej Exp $ */ #ifdef DDB @@ -166,8 +166,8 @@ void aic_timeout(void *); void aic_sched(struct aic_softc *); void aic_scsi_reset(struct aic_softc *); void aic_reset(struct aic_softc *); -void aic_free_acb(struct aic_softc *, struct aic_acb *, int); -struct aic_acb* aic_get_acb(struct aic_softc *, int); +void aic_acb_free(void *, void *); +void *aic_acb_alloc(void *); int aic_reselect(struct aic_softc *, int); void aic_sense(struct aic_softc *, struct aic_acb *); void aic_msgin(struct aic_softc *); @@ -280,6 +280,7 @@ aicattach(struct aic_softc *sc) sc->sc_link.adapter_target = sc->sc_initiator; sc->sc_link.adapter = &aic_switch; sc->sc_link.openings = 2; + sc->sc_link.pool = &sc->sc_iopool; bzero(&saa, sizeof(saa)); saa.saa_sc_link = &sc->sc_link; @@ -381,6 +382,9 @@ aic_init(struct aic_softc *sc) TAILQ_INIT(&sc->ready_list); TAILQ_INIT(&sc->nexus_list); TAILQ_INIT(&sc->free_list); + mtx_init(&sc->sc_acb_mtx, IPL_BIO); + scsi_iopool_init(&sc->sc_iopool, sc, aic_acb_alloc, + aic_acb_free); sc->sc_nexus = NULL; acb = sc->sc_acb; bzero(acb, sizeof(sc->sc_acb)); @@ -429,45 +433,34 @@ aic_init(struct aic_softc *sc) } void -aic_free_acb(struct aic_softc *sc, struct aic_acb *acb, int flags) +aic_acb_free(void *xsc, void *xacb) { - int s; - - s = splbio(); + struct aic_softc *sc = xsc; + struct aic_acb *acb = xacb; + mtx_enter(&sc->sc_acb_mtx); acb->flags = 0; TAILQ_INSERT_HEAD(&sc->free_list, acb, chain); - - /* - * If there were none, wake anybody waiting for one to come free, - * starting with queued entries. - */ - if (TAILQ_NEXT(acb, chain) == NULL) - wakeup(&sc->free_list); - - splx(s); + mtx_leave(&sc->sc_acb_mtx); } -struct aic_acb * -aic_get_acb(struct aic_softc *sc, int flags) +void * +aic_acb_alloc(void *xsc) { + struct aic_softc *sc = xsc; struct aic_acb *acb; - int s; - - s = splbio(); - while ((acb = TAILQ_FIRST(&sc->free_list)) == NULL && - (flags & SCSI_NOSLEEP) == 0) - tsleep(&sc->free_list, PRIBIO, "aicacb", 0); + mtx_enter(&sc->sc_acb_mtx); + acb = TAILQ_FIRST(&sc->free_list); if (acb) { TAILQ_REMOVE(&sc->free_list, acb, chain); acb->flags |= ACB_ALLOC; } + mtx_leave(&sc->sc_acb_mtx); - splx(s); return acb; } - + /* * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS */ @@ -507,11 +500,7 @@ aic_scsi_cmd(struct scsi_xfer *xs) sc_link->target)); flags = xs->flags; - if ((acb = aic_get_acb(sc, flags)) == NULL) { - xs->error = XS_NO_CCB; - scsi_done(xs); - return; - } + acb = xs->io; /* Initialize acb */ acb->xs = xs; @@ -856,7 +845,6 @@ aic_done(struct aic_softc *sc, struct aic_acb *acb) } else aic_dequeue(sc, acb); - aic_free_acb(sc, acb, xs->flags); ti->cmds++; scsi_done(xs); } diff --git a/sys/dev/ic/aic6360var.h b/sys/dev/ic/aic6360var.h index 07a53c9bf85..228bedf8ce0 100644 --- a/sys/dev/ic/aic6360var.h +++ b/sys/dev/ic/aic6360var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aic6360var.h,v 1.6 2006/06/03 01:51:54 martin Exp $ */ +/* $OpenBSD: aic6360var.h,v 1.7 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: aic6360.c,v 1.52 1996/12/10 21:27:51 thorpej Exp $ */ /* @@ -131,6 +131,9 @@ struct aic_softc { struct aic_acb sc_acb[8]; struct aic_tinfo sc_tinfo[8]; + struct mutex sc_acb_mtx; + struct scsi_iopool sc_iopool; + /* Data about the current nexus (updated for every cmd switch) */ u_char *sc_dp; /* Current data pointer */ size_t sc_dleft; /* Data bytes left to transfer */ diff --git a/sys/dev/ic/bha.c b/sys/dev/ic/bha.c index 6150269c24c..3c38d2e49f2 100644 --- a/sys/dev/ic/bha.c +++ b/sys/dev/ic/bha.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bha.c,v 1.26 2010/08/07 03:50:01 krw Exp $ */ +/* $OpenBSD: bha.c,v 1.27 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: bha.c,v 1.27 1998/11/19 21:53:00 thorpej Exp $ */ #undef BHADEBUG @@ -82,9 +82,9 @@ int bha_debug = 1; integrate void bha_finish_ccbs(struct bha_softc *); integrate void bha_reset_ccb(struct bha_softc *, struct bha_ccb *); -void bha_free_ccb(struct bha_softc *, struct bha_ccb *); +void bha_ccb_free(void *, void *); integrate int bha_init_ccb(struct bha_softc *, struct bha_ccb *); -struct bha_ccb *bha_get_ccb(struct bha_softc *, int); +void *bha_ccb_alloc(void *); struct bha_ccb *bha_ccb_phys_kv(struct bha_softc *, u_long); void bha_queue_ccb(struct bha_softc *, struct bha_ccb *); void bha_collect_mbo(struct bha_softc *); @@ -252,6 +252,12 @@ bha_attach(sc, bpd) struct scsibus_attach_args saa; int s; + TAILQ_INIT(&sc->sc_free_ccb); + TAILQ_INIT(&sc->sc_waiting_ccb); + + mtx_init(&sc->sc_ccb_mtx, IPL_BIO); + scsi_iopool_init(&sc->sc_iopool, sc, bha_ccb_alloc, bha_ccb_free); + /* * Fill in the adapter. */ @@ -265,9 +271,7 @@ bha_attach(sc, bpd) sc->sc_link.adapter_target = bpd->sc_scsi_dev; sc->sc_link.adapter = &sc->sc_adapter; sc->sc_link.openings = 4; - - TAILQ_INIT(&sc->sc_free_ccb); - TAILQ_INIT(&sc->sc_waiting_ccb); + sc->sc_link.pool = &sc->sc_iopool; s = splbio(); bha_inquire_setup_information(sc); @@ -459,25 +463,17 @@ bha_reset_ccb(sc, ccb) * A ccb is put onto the free list. */ void -bha_free_ccb(sc, ccb) - struct bha_softc *sc; - struct bha_ccb *ccb; +bha_ccb_free(xsc, xccb) + void *xsc, *xccb; { - int s; - - s = splbio(); + struct bha_softc *sc = xsc; + struct bha_ccb *ccb; bha_reset_ccb(sc, ccb); - TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); - /* - * If there were none, wake anybody waiting for one to come free, - * starting with queued entries. - */ - if (TAILQ_NEXT(ccb, chain) == NULL) - wakeup(&sc->sc_free_ccb); - - splx(s); + mtx_enter(&sc->sc_ccb_mtx); + TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); + mtx_leave(&sc->sc_ccb_mtx); } integrate int @@ -541,39 +537,22 @@ bha_create_ccbs(sc, ccbstore, count) /* * Get a free ccb - * - * If there are none, see if we can allocate a new one. If so, put it in - * the hash table too otherwise either return an error or sleep. */ -struct bha_ccb * -bha_get_ccb(sc, flags) - struct bha_softc *sc; - int flags; +void * +bha_ccb_alloc(xsc) + void *xsc; { + struct bha_softc *sc = xsc; struct bha_ccb *ccb; - int s; - s = splbio(); - - /* - * If we can and have to, sleep waiting for one to come free - * but only if we can't allocate a new one. - */ - for (;;) { - ccb = TAILQ_FIRST(&sc->sc_free_ccb); - if (ccb) { - TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); - break; - } - if ((flags & SCSI_NOSLEEP) != 0) - goto out; - tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0); + mtx_enter(&sc->sc_ccb_mtx); + ccb = TAILQ_FIRST(&sc->sc_free_ccb); + if (ccb) { + TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); + ccb->flags |= CCB_ALLOC; } + mtx_leave(&sc->sc_ccb_mtx); - ccb->flags |= CCB_ALLOC; - -out: - splx(s); return (ccb); } @@ -781,7 +760,6 @@ bha_done(sc, ccb) } else xs->resid = 0; } - bha_free_ccb(sc, ccb); scsi_done(xs); } @@ -1278,14 +1256,7 @@ bha_scsi_cmd(xs) * then we can't allow it to sleep */ flags = xs->flags; - if ((ccb = bha_get_ccb(sc, flags)) == NULL) { - xs->error = XS_NO_CCB; - scsi_done(xs); - splx(s); - return; - } - - splx(s); /* done playing with the queue */ + ccb = xs->io; ccb->xs = xs; ccb->timeout = xs->timeout; @@ -1395,7 +1366,6 @@ bha_scsi_cmd(xs) bad: xs->error = XS_DRIVER_STUFFUP; - bha_free_ccb(sc, ccb); scsi_done(xs); } diff --git a/sys/dev/ic/bhavar.h b/sys/dev/ic/bhavar.h index a089845d397..577fb6de851 100644 --- a/sys/dev/ic/bhavar.h +++ b/sys/dev/ic/bhavar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bhavar.h,v 1.4 2008/11/26 16:38:00 krw Exp $ */ +/* $OpenBSD: bhavar.h,v 1.5 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: bhavar.h,v 1.12 1998/11/19 21:53:00 thorpej Exp $ */ /*- @@ -84,6 +84,9 @@ struct bha_softc { struct scsi_link sc_link; /* prototype for devs */ struct scsi_adapter sc_adapter; + struct mutex sc_ccb_mtx; + struct scsi_iopool sc_iopool; + char sc_model[7]; char sc_firmware[6]; }; diff --git a/sys/dev/ic/oosiop.c b/sys/dev/ic/oosiop.c index 5f922ff3448..91cba5d4de3 100644 --- a/sys/dev/ic/oosiop.c +++ b/sys/dev/ic/oosiop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: oosiop.c,v 1.17 2010/06/28 18:31:02 krw Exp $ */ +/* $OpenBSD: oosiop.c,v 1.18 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: oosiop.c,v 1.4 2003/10/29 17:45:55 tsutsui Exp $ */ /* @@ -90,6 +90,9 @@ void oosiop_setup(struct oosiop_softc *, struct oosiop_cb *); void oosiop_poll(struct oosiop_softc *, struct oosiop_cb *); void oosiop_processintr(struct oosiop_softc *, u_int8_t); +void *oosiop_cb_alloc(void *); +void oosiop_cb_free(void *, void *); + /* Trap interrupt code for unexpected data I/O */ #define DATAIN_TRAP 0xdead0001 #define DATAOUT_TRAP 0xdead0002 @@ -135,6 +138,32 @@ struct scsi_adapter oosiop_adapter = { NULL }; +void * +oosiop_cb_alloc(void *xsc) +{ + struct oosiop_softc *sc = xsc; + struct oosiop_cb *cb; + + mtx_enter(&sc->sc_cb_mtx); + cb = TAILQ_FIRST(&sc->sc_free_cb); + if (cb) + TAILQ_REMOVE(&sc->sc_free_cb, cb, chain); + mtx_leave(&sc->sc_cb_mtx); + + return (cb); +} + +void +oosiop_cb_free(void *xsc, void *xcb) +{ + struct oosiop_softc *sc = xsc; + struct oosiop_cb *cb = xcb; + + mtx_enter(&sc->sc_cb_mtx); + TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); + mtx_leave(&sc->sc_cb_mtx); +} + void oosiop_attach(struct oosiop_softc *sc) { @@ -715,8 +744,8 @@ oosiop_scsicmd(struct scsi_xfer *xs) sc = (struct oosiop_softc *)xs->sc_link->adapter_softc; s = splbio(); - cb = TAILQ_FIRST(&sc->sc_free_cb); - TAILQ_REMOVE(&sc->sc_free_cb, cb, chain); + + cb = xs->io; cb->xs = xs; cb->xsflags = xs->flags; @@ -735,10 +764,9 @@ oosiop_scsicmd(struct scsi_xfer *xs) if (err) { printf("%s: unable to load cmd DMA map: %d", sc->sc_dev.dv_xname, err); + splx(s); xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); - TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); - splx(s); return; } bus_dmamap_sync(sc->sc_dmat, cb->cmddma, 0, xs->cmdlen, @@ -757,11 +785,10 @@ oosiop_scsicmd(struct scsi_xfer *xs) if (err) { printf("%s: unable to load data DMA map: %d", sc->sc_dev.dv_xname, err); - xs->error = XS_DRIVER_STUFFUP; bus_dmamap_unload(sc->sc_dmat, cb->cmddma); - scsi_done(xs); - TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); splx(s); + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); return; } bus_dmamap_sync(sc->sc_dmat, cb->datadma, @@ -937,7 +964,6 @@ oosiop_done(struct oosiop_softc *sc, struct oosiop_cb *cb) FREE: xs->resid = 0; scsi_done(xs); - TAILQ_INSERT_TAIL(&sc->sc_free_cb, cb, chain); if (cb == sc->sc_curcb) sc->sc_curcb = NULL; diff --git a/sys/dev/ic/oosiopvar.h b/sys/dev/ic/oosiopvar.h index 85837139e5b..617673b198d 100644 --- a/sys/dev/ic/oosiopvar.h +++ b/sys/dev/ic/oosiopvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: oosiopvar.h,v 1.4 2010/04/20 20:21:56 miod Exp $ */ +/* $OpenBSD: oosiopvar.h,v 1.5 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: oosiopvar.h,v 1.2 2003/05/03 18:11:23 wiz Exp $ */ /* @@ -139,6 +139,9 @@ struct oosiop_softc { TAILQ_HEAD(oosiop_cb_queue, oosiop_cb) sc_free_cb, sc_cbq; + struct mutex sc_cb_mtx; + struct scsi_iopool sc_iopool; + struct oosiop_cb *sc_curcb; /* current command */ struct oosiop_cb *sc_lastcb; /* last activated command */ diff --git a/sys/dev/ic/uha.c b/sys/dev/ic/uha.c index feb5379744e..2b511d86d0a 100644 --- a/sys/dev/ic/uha.c +++ b/sys/dev/ic/uha.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uha.c,v 1.21 2010/08/07 03:50:01 krw Exp $ */ +/* $OpenBSD: uha.c,v 1.22 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: uha.c,v 1.3 1996/10/13 01:37:29 christos Exp $ */ #undef UHADEBUG @@ -83,9 +83,9 @@ #define KVTOPHYS(x) vtophys((vaddr_t)x) integrate void uha_reset_mscp(struct uha_softc *, struct uha_mscp *); -void uha_free_mscp(struct uha_softc *, struct uha_mscp *); +void uha_mscp_free(void *, void *); integrate void uha_init_mscp(struct uha_softc *, struct uha_mscp *); -struct uha_mscp *uha_get_mscp(struct uha_softc *, int); +void *uha_mscp_alloc(void *); void uhaminphys(struct buf *, struct scsi_link *); void uha_scsi_cmd(struct scsi_xfer *); @@ -129,6 +129,9 @@ uha_attach(sc) (sc->init)(sc); SLIST_INIT(&sc->sc_free_mscp); + mtx_init(&sc->sc_mscp_mtx, IPL_BIO); + scsi_iopool_init(&sc->sc_iopool, sc, uha_mscp_alloc, uha_mscp_free); + /* * fill in the prototype scsi_link. */ @@ -136,6 +139,7 @@ uha_attach(sc) sc->sc_link.adapter_target = sc->sc_scsi_dev; sc->sc_link.adapter = &uha_switch; sc->sc_link.openings = 2; + sc->sc_link.pool = &sc->sc_iopool; bzero(&saa, sizeof(saa)); saa.saa_sc_link = &sc->sc_link; @@ -159,25 +163,17 @@ uha_reset_mscp(sc, mscp) * A mscp (and hence a mbx-out) is put onto the free list. */ void -uha_free_mscp(sc, mscp) - struct uha_softc *sc; - struct uha_mscp *mscp; +uha_mscp_free(xsc, xmscp) + void *xsc, *xmscp; { - int s; - - s = splbio(); + struct uha_softc *sc = xmscp; + struct uha_mscp *mscp; uha_reset_mscp(sc, mscp); - SLIST_INSERT_HEAD(&sc->sc_free_mscp, mscp, chain); - /* - * If there were none, wake anybody waiting for one to come free, - * starting with queued entries. - */ - if (SLIST_NEXT(mscp, chain) == NULL) - wakeup(&sc->sc_free_mscp); - - splx(s); + mtx_enter(&sc->sc_mscp_mtx); + SLIST_INSERT_HEAD(&sc->sc_free_mscp, mscp, chain); + mtx_leave(&sc->sc_mscp_mtx); } integrate void @@ -201,51 +197,22 @@ uha_init_mscp(sc, mscp) /* * Get a free mscp - * - * If there are none, see if we can allocate a new one. If so, put it in the - * hash table too otherwise either return an error or sleep. */ -struct uha_mscp * -uha_get_mscp(sc, flags) - struct uha_softc *sc; - int flags; +void * +uha_mscp_alloc(xsc) + void *xsc; { + struct uha_softc *sc = xsc; struct uha_mscp *mscp; - int s; - - s = splbio(); - /* - * If we can and have to, sleep waiting for one to come free - * but only if we can't allocate a new one - */ - for (;;) { - mscp = SLIST_FIRST(&sc->sc_free_mscp); - if (mscp) { - SLIST_REMOVE_HEAD(&sc->sc_free_mscp, chain); - break; - } - if (sc->sc_nummscps < UHA_MSCP_MAX) { - mscp = (struct uha_mscp *) malloc(sizeof(struct uha_mscp), - M_TEMP, M_NOWAIT); - if (!mscp) { - printf("%s: can't malloc mscp\n", - sc->sc_dev.dv_xname); - goto out; - } - uha_init_mscp(sc, mscp); - sc->sc_nummscps++; - break; - } - if ((flags & SCSI_NOSLEEP) != 0) - goto out; - tsleep(&sc->sc_free_mscp, PRIBIO, "uhamsc", 0); + mtx_enter(&sc->sc_mscp_mtx); + mscp = SLIST_FIRST(&sc->sc_free_mscp); + if (mscp) { + SLIST_REMOVE_HEAD(&sc->sc_free_mscp, chain); + mscp->flags |= MSCP_ALLOC; } + mtx_leave(&sc->sc_mscp_mtx); - mscp->flags |= MSCP_ALLOC; - -out: - splx(s); return (mscp); } @@ -319,7 +286,7 @@ uha_done(sc, mscp) } else xs->resid = 0; } - uha_free_mscp(sc, mscp); + scsi_done(xs); } @@ -355,11 +322,8 @@ uha_scsi_cmd(xs) * then we can't allow it to sleep */ flags = xs->flags; - if ((mscp = uha_get_mscp(sc, flags)) == NULL) { - xs->error = XS_NO_CCB; - scsi_done(xs); - return; - } + mscp = xs->io; + mscp->xs = xs; mscp->timeout = xs->timeout; timeout_set(&xs->stimeout, uha_timeout, xs); @@ -485,7 +449,6 @@ uha_scsi_cmd(xs) bad: xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); - uha_free_mscp(sc, mscp); return; } diff --git a/sys/dev/ic/uhavar.h b/sys/dev/ic/uhavar.h index 64308b6b42e..93d9896e516 100644 --- a/sys/dev/ic/uhavar.h +++ b/sys/dev/ic/uhavar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uhavar.h,v 1.3 2010/06/30 19:06:16 mk Exp $ */ +/* $OpenBSD: uhavar.h,v 1.4 2011/04/03 12:42:36 krw Exp $ */ /* $NetBSD: uhavar.h,v 1.3 1996/10/21 22:34:43 thorpej Exp $ */ /* @@ -50,6 +50,10 @@ struct uha_softc { struct uha_mscp *sc_mscphash[MSCP_HASH_SIZE]; SLIST_HEAD(, uha_mscp) sc_free_mscp; + + struct mutex sc_mscp_mtx; + struct scsi_iopool sc_iopool; + int sc_nummscps; int sc_scsi_dev; /* our scsi id */ struct scsi_link sc_link; |